节点并发/快速请求生命周期/可能的竞争条件?

时间:2015-08-27 15:52:55

标签: node.js asynchronous express

我正在构建一个多租户节点应用程序,其中通过查询字符串识别租户。

我还有一个API客户端,可以根据网站发出经过身份验证的(oauth)请求。

我的问题是我是否可以将API客户端保留为单个对象,并且只更新其中的会话 - 以及我是否会因为同时进入另一个请求而遇到竞争条件而我# 39; m与客户端进行异步操作。

const session = new Session({ apiKey: 'xxx', secret: 'xxx' })

const client = new Client({ session })

app.use((req, res, next)=> {
  res.locals.client = client;
  next()
})

app.use((req, res, next)=> {
  let { client, db } = res.locals;
  if (req.query.tenant) {
    return db.Tenant.findOne({ tenant: req.query.tenant })
      .then((tenant)=> {
        client.updateSession({ 
          access_token: tenant ? tenant.access_token : null 
        })
        next()
      })
  }
  next();
})

app.get('/test/api', (req, res)=> {
  let { client } = res.locals;
  client.get('products').then((products)=> {
    // What if another request from another tenant comes in right here?
    // Is it possible for the session to be swapped out underneath me?
    return products.get(2).someAsyncFunc().then((product)=> {
      return res.json(product)
    })
  })
})

1 个答案:

答案 0 :(得分:2)

  

我的问题是我是否可以将API客户端作为单个对象保留,只是更新其中的会话

不,为每个请求创建Client对象的唯一实例。绝对client.updateSession看起来像是用非共享数据污染共享对象。

只需更改此行

即可
res.locals.client = client;

到此:

res.locals.client = new Client(new Session({apiKey: 'x', secret: 'x'}));

你现在应该安全了。