如何在Nest的Bull Queue中检测重复任务添加情况?
解决Bull Queue重复任务判断问题
你可以通过以下几种方式区分任务是新增还是返回已有重复任务:
方法一:对比任务创建时间
调用add方法后,返回的job对象包含createdAt字段,记录了任务最初创建的时间。将这个时间和调用add的当前时间做对比,如果两者差值极小(比如小于100ms,可根据业务调整),说明是新创建的任务;反之则是已存在的重复任务。
示例代码:
const currentTime = Date.now(); const job = await this.sglQueue.add(jobName, jobData, { delay: (jobDelay * 1000), timeout: (jobTimeout * 1000), lifo: jobLIFO, removeOnFail: false, removeOnComplete: true, jobId: jobId, }); const isNewJob = Math.abs(job.createdAt.getTime() - currentTime) < 100; if (isNewJob) { // 任务是新增的 } else { // 任务是重复的,返回已有任务 }
方法二:先查询再添加(需注意竞态)
先调用getJob方法查询对应jobId的任务是否存在,不存在再执行添加操作。但要注意,这种方式存在竞态条件——如果在查询和添加之间,其他进程/线程添加了相同jobId的任务,add仍会返回已有任务,所以后续还是需要结合方法一的判断。
示例代码:
const existingJob = await this.sglQueue.getJob(jobId); let job; let isNewJob = false; if (!existingJob) { job = await this.sglQueue.add(jobName, jobData, { delay: (jobDelay * 1000), timeout: (jobTimeout * 1000), lifo: jobLIFO, removeOnFail: false, removeOnComplete: true, jobId: jobId, }); isNewJob = true; } else { job = existingJob; isNewJob = false; } // 处理逻辑
方法三:利用Bull的add返回值属性
部分Bull版本中,返回的job对象会带有isNew属性,可直接通过该属性判断:
const job = await this.sglQueue.add(jobName, jobData, { delay: (jobDelay * 1000), timeout: (jobTimeout * 1000), lifo: jobLIFO, removeOnFail: false, removeOnComplete: true, jobId: jobId, }); if (job.isNew) { // 新增任务 } else { // 重复任务 }
注意:如果你的Bull版本没有isNew属性,优先使用方法一,精度和可靠性更高。
内容的提问来源于stack exchange,提问作者mubashir
相关产品推荐
相关产品推荐

