Express:每秒运行一次中间件

时间:2016-09-14 11:48:44

标签: node.js express mongoose

我有一个作为API运行的快速服务器,我有一个中间件加载:

app.js

const lastActivity = require('./middleware/lastActivity');
app.use(lastActivity);`

中间件/ lastActivity.js

module.exports = function(req, res, next) {
    if (req.user && isDifferentDay(req.user.last_activity) {
        User.findById(req.user.id, (err, user) => {
            user.last_activity = Date.now();
            user.save((err) => {
                // also do another async call to an external service, then
                return next();
            }
        });
    }
});

因此它检查用户保存的last_activity日期是否与今天不同,如果是,则更新用户(我只关心日期,而不是特定的时间戳)。它还对外部服务进行API调用以管理电子邮件营销活动。

但问题是我的网络应用程序同时在页面加载时请求两个资源。这意味着isDifferentDay对它们都返回true,并且用户模型更新两次,更重要的是我对外部服务进行两次API调用,这是对速率的限制。

一个明显的解决方案是一次只在我的客户端上做一个请求,但我并不想限制自己。我想要的是一种快速锁定'每秒只运行一次中间件?或者其他一些我无法看到的解决方案。

以快速/节点方式处理此问题的最佳方法是什么?

谢谢。

1 个答案:

答案 0 :(得分:1)

这个问题是典型的竞争条件 由于您每天只关心用户last_activity一次,而不是使用findById,您可以为数据库请求添加额外的过滤器并一次更新。 E.g。

var query = { 
    _id: req.user.id,
    last_activity: req.user.last_activity
};
User.findOneAndUpdate(query, { last_activity: Date.now() }, (err, user) => {
    if (!user)
        return; // user was changed between requests, do nothing
    // ... the rest of your code
});

这样,只有在您的操作之间保持last_activity不变的情况下,您才会更新用户。