服务器 1 如何可靠地知道服务器 2 何时完成了特定工作? (bull.js)

How can server 1 know reliably when server 2 has completed a specific job? (bull.js)

服务器 1 正在调用此函数:

let job = await transactions.add({ foo: 'bar' });
let status = await job.finished();
console.log(status);

服务器 2 正在使用如下作业:

transactions.process(QueueOptions.maxConcurrent, async (job, done) => {
    done(null, {result: job.data});
});

但是,当该作业完成时,服务器 1 没有收到通知。 job.finished() 唯一解决的问题是服务器 1 将作业排队,然后服务器 2 启动。在这种情况下,job.finished() 承诺有效。否则总是沉默

服务器 1 如何可靠地知道服务器 2 何时完成了作业? (完成一项工作需要 10 秒或更短的时间)

您至少有两个选项可以实现将一个作业完成的结果从一台服务器中的处理器通知另一台服务器。

选项 1

使用全局事件并监听 "completed" 事件。例如:

// Server 1
transactions.on("global:completed", (jobId, result) => {
  // Job completed
}); 

此选项的优点是简单明了。但是,在 Bull 3.x 中,事件并不保证总是到达目的地,例如在网络分区或 Redis 断开连接的情况下。如果你能接受极少数的结果没有被完全通知,你可以使用这种方法。

选项 2

使用此处描述的返回作业完成模式:https://github.com/OptimalBits/bull/blob/develop/PATTERNS.md#returning-job-completions

它通过定义一个新的队列来工作,我们称之为 results,您可以在完成之前添加处理器的结果,如下所示:

// Server 2
transactions.process(QueueOptions.maxConcurrent, async (job) => {
  const result = {result: job.data}
  await results.add(job.data);
  return result
});

在需要监听结果的服务器上,创建一个处理结果的处理器即可:

// Server 1
results.process( (job) => {
  // Do something with the result from the transaction queue...
});

此解决方案的优点是稳健性。基本上,您永远不会丢失事务队列中的任何结果,但会增加一些代码复杂性。

我和OP有同样的问题。接受的答案有效并帮助我解决了大部分问题,但您仍然需要建立一种方法来实际获得工作结果。

我正在寻找让我做的事情:

const result = await jobQueue.doJob('foo', {foo: 'bar'});

使用上面选项 1 中描述的策略,我构建了一个工具,希望登陆这里的其他人会发现它有用

它的要点是使用进程范围的 EventEmitter 注册并删除 Bull 'global:completed' 和 'global:failed' 事件的侦听器。然后我将带有解决或拒绝的 Promise 映射到对 jobQueue.doJob 的特定调用 链接如下:

https://www.npmjs.com/package/bullrack https://github.com/joewagner/bullrack

希望这可以节省一些人的时间。该软件包仍需要测试,但非常欢迎反馈。