我正在编写一个批处理来构建一些日志类型条目。它将是我的API的一个单独的应用程序,它只会执行这一项任务。现在,我有一个Express API,其中包含一个logMsg传递到的端点。这些来自许多用户,每个用户每10秒左右发送一个。为了保持移动,我在logMsg上做了几个简单的操作,并将它粘贴到我的Postgres DB中。
现在我想迭代这些消息以构建一些logEntries,以便我可以更轻松地计算活动期间所花费的时间。每个logMsg在进入时,都有一个活动(或缺少一个),一个用户和一个时间戳。 LogEntry具有user,activity,startTime和endTime。这样,API应用程序可以更轻松地计算用户或活动为一组用户执行/不执行活动所花费的时间。
所以我想设置一个批处理作业,它抓取一些n个未处理的点,将它们标记为正在处理中,然后处理它们,然后将它们标记为完整。我遇到麻烦的地方就是把事情做好。
let activityLogJob = new CronJob('30 * * * * *', function() {
return knex
.raw() //grab a chunk of rows and mark as In Progress
.then((processingRows) => {
_.forEach(logMsgs, (msg) => {
console.log('message id:', msg.id);
return knex.select() //latest log entry for msg.user
.then((logEntry) => {
if (logEntry) {
if (logEntry.activity_id !== msg.activity_id) {
console.log('new activity started. end old one');
return knex.transaction( (trx) => {
trx
.update() //logEntry.endTime = msg.startTime
.then((update) => {
trx
.insert(); //create new logEntry for new activity
});
});
}
} else {
console.log('first log entry for user');
knex
.insert(); //create new logEntry since we don't have one for the user
}
})
.then((result) => {
console.log('finished msg :', msg.id);
knex
.update(); //set msg.status = LOGGED
})
.catch((err) => {
logger.error("ERROR: ", err);
});
});
});
}, null, true);
所以我在上面的代码中看到的是它可以很好地抓取所有行,但是当它实际处理它们时会变得很奇怪。日志语句显示如下:
message 1
first log entry for user
message 2
first log entry for user
...
message n
first log entry for user
finished message 1
finished message 2
...
finished message n
所以我认为这里有两个问题 1.它永远不会找到现有的LogEntry并且每次都会创建一个新的LogEntry。感觉就像在处理完所有消息之后插件都没有发生 我原本期望日志语句更像是
message 1
first entry for user
finished message 1
message 2
first entry for user
finished message 2
...
我很确定我的问题是我还没有正确地绕着承诺包裹我的脑袋。
答案 0 :(得分:0)
您需要返回嵌套在另一个承诺的回调中的所有承诺。如果你不这样做,那么嵌套承诺的结果就不会通过链传递。这应该有助于您的邮件同步。
return knex
.raw() //grab a chunk of rows and mark as In Progress
.then((processingRows) => {
_.forEach(logMsgs, (msg) => {
console.log('message id:', msg.id);
return knex.select() //latest log entry for msg.user
.then((logEntry) => {
if (logEntry) {
if (logEntry.activity_id !== msg.activity_id) {
console.log('new activity started. end old one');
return knex.transaction( (trx) => {
return trx #####
.update() //logEntry.endTime = msg.startTime
.then((update) => {
return trx #####
.insert(); //create new logEntry for new activity
});
});
}
} else {
console.log('first log entry for user');
return knex #####
.insert(); //create new logEntry since we don't have one for the user
}
})
.then((result) => {
console.log('finished msg :', msg.id);
return knex #####
.update(); //set msg.status = LOGGED
})
.catch((err) => {
logger.error("ERROR: ", err);
});
});
});