简体   繁体   English

公牛队列:当一个作业失败时,如何停止队列处理剩余的作业?

[英]Bull queue: When a job fails, how to stop queue from processing remaining jobs?

I am using bull queue to process some jobs.我正在使用公牛队列来处理一些工作。 In the current scenario each job is some kind of an operation.在当前场景中,每个作业都是某种操作。 So whenever an operation(job) among a list of operations in the queue fails, queue has to stop processing the remaining jobs(operations).因此,每当队列中操作列表中的一个操作(作业)失败时,队列必须停止处理剩余的作业(操作)。

What have I tried so far?到目前为止我尝试了什么?

So i tried to pause the queue when a particular job fails.因此,当特定作业失败时,我尝试暂停队列。 Next the queue is resumed when it drains.接下来,队列在耗尽时恢复。 Now when it is resumed the queue does not start from the failed job instead picks up the next job.现在,当它恢复时,队列不会从失败的作业开始,而是选择下一个作业。

var Queue = require('bull');

let redisOptions = {
  redis: { port: 6379, host: '127.0.0.1' },
  limiter: { max: 1, duration: 1000 }
}
var myQueue = new Queue('Linear-Queue', redisOptions);

myQueue.process('Type-1', function (job, done) {
  setTimeout(() => {
    done(job.data.error);
  }, job.data.time);
});

let options = {
  attempts: 3,
  removeOnComplete: false, // removes job from queue on success
  removeOnFail: false // removes job from queue on failure
}

setTimeout(() => {
  myQueue.add('Type-1', { time: 10000, description: "Type-1 One", error: false }, options);
}, 1 * 1000);

setTimeout(() => {
  myQueue.add('Type-1', { time: 5000, description: "Type-1 two", error: true }, options);
}, 2 * 1000);

setTimeout(() => {
  myQueue.add('Type-1', { time: 3000, description: "Type-1 three", error: false }, options);
}, 3 * 1000);


myQueue.on('completed', function (job, result) {
  console.log("Completed: " + job.data.description);
});

myQueue.on('failed', async function (job, error) {
  console.log("Failed: " + job.data.description);
  try {
    await myQueue.pause();
  } catch (error) {
    console.log(error);
  }
});

myQueue.on('drained', async function () {
  try {
    await myQueue.resume();
  } catch (error) {
    console.log(error);
  }
});

Current Output:当前 Output:

当前结果

Expected Output: if the Type-1 two completes successfully in 3rd attempt.预期的 Output:如果Type-1 two在第三次尝试中成功完成。

Completed: Type-1 One
Failed: Type-1 two
Failed: Type-1 two
Completed: Type-1 two
Completed: Type-1 three

Expected Output: if the Type-1 two failed in 3rd attempt as well.预期的 Output:如果Type-1 two在第三次尝试中也失败了。

Completed: Type-1 One
Failed: Type-1 two
Failed: Type-1 two
Failed: Type-1 two

All i want is the queue has to stop processing new jobs until current job is completed without any failure.我想要的只是队列必须停止处理新作业,直到当前作业完成而没有任何失败。 In case of any failure, the failed job has to run some x number of time.如果发生任何故障,失败的作业必须运行x次。 At the x+1 attempt it has to clear(delete all jobs) the queue.在第x+1次尝试时,它必须清除(删除所有作业)队列。 So how to achieve this linear behavior in queue.那么如何在队列中实现这种线性行为。

In bull Its not possible to repeat the same job immediately after its failure before picking up the next job in the queue.bull中,它不可能在失败后立即重复相同的工作,然后再拿起队列中的下一个工作。

Solution:解决方案:

  1. Create new job and set its priority to a value less than the current job type.创建新作业并将其优先级设置为小于当前作业类型的值。
  2. Release the failed job ( resolve() or done() )释放失败的作业( resolve()done()
  3. This new job will be picked up immediately by the bull for processing.这份新工作将立即被bull接手处理。

Sample code: In the below code Job-3 will fail and create new job and so on until "purpose of the job" succeeds at some point of time.示例代码:在下面的代码中, Job-3将失败并创建新作业,依此类推,直到“作业目的”在某个时间点成功。

var Queue = require('bull');

let redisOptions = {
  redis: { port: 6379, host: '127.0.0.1' }
}
var myQueue = new Queue('Linear-Queue', redisOptions);

myQueue.process('Type-1', function (job, done) {
  console.log(`Processing Job-${job.id} Attempt: ${job.attemptsMade}`);
  downloadFile(job, async function (error) {
    if (error) {
      await repeatSameJob(job, done);
    } else {
      done();
    }
  });
});

async function repeatSameJob(job, done) {
  let newJob = await myQueue.add('Type-1', job.data, { ...{ priority: 1 }, ...job.opts });
  console.log(`Job-${job.id} failed. Creating new Job-${newJob.id} with highest priority for same data.`);
  done(true);
}

function downloadFile(job, done) {
  setTimeout(async () => {
    done(job.data.error)
  }, job.data.time);
}

myQueue.on('completed', function (job, result) {
  console.log("Completed: Job-" + job.id);
});

myQueue.on('failed', async function (job, error) {
  console.log("Failed: Job-" + job.id);
});

let options = {
  removeOnComplete: true, // removes job from queue on success
  removeOnFail: true // removes job from queue on failure
}

for (let i = 1; i <= 5; i++) {
  let error = false;
  if (i == 3) { error = true; }

  setTimeout(i => {
    let jobData = {
      time: i * 2000,
      error: error,
      description: `Job-${i}`
    }
    myQueue.add('Type-1', jobData, options);
  }, i * 2000, i);
}

Output: Output:

输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM