功能说明
后台任务失败后立即丢弃会丢失数据,无限重试又会阻塞队列。该队列在内存中重试任务,达到最大次数后移入死信队列,记录错误信息与失败时间,便于人工检查或补偿。它适合邮件发送、Webhook 投递和批量导入等需要保留失败现场的场景。
关键代码
Job 保存 id、payload 与尝试次数。drain 循环取出任务并递增 attempts,成功计入 processed;失败且未达上限时重新入队,达到上限则写入 deadLetters。maxAttempts 与时钟均可注入,便于测试。listDeadLetters 返回副本,避免外部直接修改内部数组。
if (job.attempts < this.maxAttempts) {
this.pending.push(job);
} else {
this.deadLetters.push({ job, error: message, failedAt: this.now() });
deadLettered += 1;
}
使用注意
该实现是单进程内存队列,重启会丢失任务。重试没有退避延迟,可能快速耗尽次数。处理器应保证幂等,因为失败任务可能已产生部分副作用。死信只保存在内存中,生产环境应持久化到数据库或专用队列。drain 会一直处理到队列为空。
验证方式
断言处理器连续失败三次后任务进入死信,deadLetterCount 为 1,错误信息与时间被记录。maxAttempts 为 1 时首次失败即进入死信。成功任务使 processed 加一。maxAttempts 为 0 抛 RangeError,空 id 抛 TypeError,处理器非函数抛 TypeError。