在你的代码中,await job.moveToFailed({ message: 'Failed due to conditions' });
在 active
事件处理器中被调用,这可能导致问题。
原因
- 状态变化:当一个任务被标记为“active”时,Bull 会在它的
process
方法中处理这个任务。如果在active
事件处理器中调用moveToFailed
,它会尝试将任务移到失败队列,但此时 Bull 可能已经在处理这个任务,导致状态不一致。 - 任务逻辑:如果你在
active
事件中尝试将任务标记为失败,那么process
方法中的逻辑可能没有机会执行,或执行结果会因为任务已经被标记为失败而失效。
正确的做法
如果你想根据某些条件在任务处理时将其标记为失败,应该在 process
方法中进行,而不是在 active
事件处理器中。以下是修正后的代码示例:
javascript复制代码const Queue = require('bull');
const myQueue = new Queue('myQueue');
// 处理队列中的任务
myQueue.process(async (job) => {
console.log(`Processing job: ${job.id}`);
const shouldFail = false; // 你的条件逻辑
if (shouldFail) {
throw new Error("任务失败"); // 抛出错误以标记任务为失败
}
// 任务成功完成
return { message: '任务成功完成' };
});
// 监听 active 事件
myQueue.on('active', (job) => {
console.log(`Job is now active: ${job.id}, ${JSON.stringify(job)}`);
});
// 监听 failed 事件
myQueue.on('failed', (job, err) => {
console.log(`Job failed: ${job.id}, Error: ${err.message}`);
});
// 监听 completed 事件
myQueue.on('completed', (job, result) => {
console.log(`Job completed: ${job.id}, ${JSON.stringify(job)}, Result: ${JSON.stringify(result)}`);
});
// 添加任务
myQueue.add({ data: 'example' });
总结
- 在
process
方法中进行失败处理:使用throw new Error(...)
在任务处理逻辑中标记任务失败。 - 避免在
active
事件中使用moveToFailed
:只需监控任务状态,无需在此处处理失败逻辑。这样可以确保任务逻辑清晰并且不会造成状态冲突。