【问题标题】:NodeJS Bull Stop the queue jobs on a job failedNodeJS Bull 停止作业上的队列作业失败
【发布时间】:2020-05-02 20:05:52
【问题描述】:

我的NodeJS 项目中有多个Bull 队列,如果前一个队列成功执行,它们将运行。 我正在尝试在这里验证一些电子邮件地址。

  1. 检查电子邮件格式(formatQueue)

  2. Email Existence 使用npm email-existence 包(existenceQueue)

formatQueue 是一个耗时较少的过程,它将运行 RegEx 并验证 Email 格式。但是email-existence 包大约需要 5-10 秒才能完成。

formatQueueexistenceQueue 如果 jobs 较少,例如 20-100,则可以正常工作。但是当我一次添加超过 1000 个工作时,existenceQueue 失败并出现以下错误

myemail@email.com job stalled more than allowable limit

我检查了问题HEREHERE,我认为这个过程需要很长时间才能响应,所以添加limiter 作为参考HERE。但这对我没有帮助。

如果任何队列中的作业失败,它不会处理下一个作业。它将停在那里,其他工作将保持在waiting 状态。

我的代码类似于下面的代码。请帮我解决这个问题。

Queue.js

var formatQueue = new Queue('format', "redis-db-url");
var existenceQueue = new Queue('existence', "redis-db-url");

// ------------ function for adding to queue ------------
module.exports.addToQueue = (emails) => {
    emails.forEach(element => {
        formatQueue.add(element, { attempts: 3, backoff: 1000 });
    });
}

// ------------ Queue Process -------------

// Format Test Process
formatQueue.process(function(job, done){
    FormatTest.validate(job.data, (err, data) => {
        if(err) done();
        else{
            job.data = data;
            done();
        }
    });
});

// Existence Test Process
formatQueue.process(function(job, done){
    ExistenceTest.validate(job.data, (err, data) => {
        if(err) done();
        else{
            job.data = data;
            done();
        }
    });
});


// ------------ On Cmplete Handlers ------------
formatQueue.on('completed', function(job){
    if(job.data.is_well_format){
        existenceQueue.add(job.data, { attempts: 3, backoff: 1000 });
    }else QueueModel.lastStep(job.data)
});

existenceQueue.on('completed', function(job){
    QueueModel.lastStep(job.data)
});


// ------------ To update the emaile ------------
module.exports.lastStep = (data) => {
    Emails.updateEmail(data, (err, updated) => {
        if(!err) {
            formatQueue.clean('completed');
            existenceQueue.clean('completed');
        }
    })
}

--------- 更新 ---------

处理器响应时间过长,因此作业收到 stalled 或由于我使用超时而失败。

我正在尝试在不同的processor 文件中运行process,就像在bull 文档中一样,我添加了如下文件。

// -------- Queue.js ----------

formatQueue.process(__dirname+"/processors/format-worker.js");


// On Cmplete Handler

formatQueue.on('completed', function(job, result){
    console.log(result, "Format-Complete-job"); // result is undefined
    if(job.data.is_well_format){
        existenceQueue.add(job.data, { attempts: 3, backoff: 1000 });
    }else QueueModel.lastStep(job.data)
});

// -------- Queue.js ends ---------

//format-worker.js
Validator = require("../../validators");
module.exports = (job) => {
    Validator.Format.validate(job.data, (data) => {
        job.data = data;
        return Promise.resolve(data);
    });
}

现在在我之前使用的作业完成时,我曾经使用更新的作业参数获取作业数据。现在我没有得到更新的工作数据。文档中的第二个参数,即resultundefined。 现在如何在这种情况下获取更新的作业数据。

【问题讨论】:

  • 这个队列行为正是我想在这里的问题中实现的:stackoverflow.com/questions/61659677/…
  • 你好,伙计,在你的情况下,你想停止队列,但在我的情况下,我想更新作业数据并继续处理其他数据。

标签: node.js queue job-queue bull.js bull-queue


【解决方案1】:

尝试可重复的工作

var formatQueue = new Queue('format', "redis-db-url");
var existenceQueue = new Queue('existence', "redis-db-url");

// ------------ function for adding to queue ------------
module.exports.addToQueue = (emails) => {
  emails.forEach(element => {
    let jobOptions = {
      repeat: {
        every: 10 * 1000, // Run job every 10 seconds for example
        limit: 3 // Maximum number of times a job can repeat.
      },
      jobId: someUniqueId, // important do not forget this
      removeOnComplete: true, // removes job from queue on success (if required)
      removeOnFail: true // removes job from queue on failure (if required)
    }

    formatQueue.add(element, jobOptions);
  });
}

// ------------ Queue Process -------------

// Format Test Process
formatQueue.process(function (job, done) {
  FormatTest.validate(job.data, (err, data) => {
    if (err) {
      // Done with error
      done(true);
    } else {
      job.data = data;
      // Done without any error
      done(false);
    }
  });
});

// Existence Test Process
existenceQueue.process(function (job, done) {
  ExistenceTest.validate(job.data, (err, data) => {
    if (err) {
      // Done with error
      done(true);
    } else {
      job.data = data;
      // Done without any error
      done(false);
    }
  });
});


// ------------ On Complete Handlers ------------
formatQueue.on('completed', function (job) {
  if (job.data.is_well_format) {
    let jobOptions = {
      repeat: {
        every: 10 * 1000, // Run job every 10 seconds for example
        limit: 3 // Maximum number of times a job can repeat.
      },
      jobId: someUniqueId, // important do not forget this
      removeOnComplete: true, // removes job from queue on success (if required)
      removeOnFail: true // removes job from queue on failure (if required)
    }

    existenceQueue.add(job.data, jobOptions);
  } else QueueModel.lastStep(job.data)
});

existenceQueue.on('completed', function (job) {
  QueueModel.lastStep(job.data)
});


// ------------ To update the email ------------
module.exports.lastStep = (data) => {
  Emails.updateEmail(data, (err, updated) => {
    if (!err) {
      formatQueue.clean('completed');
      existenceQueue.clean('completed');
    }
  })
}

【讨论】:

  • 您好,我认为这与工作重复,对吗?它与该错误有何关系?你能解释一下吗!让我以后能有更好的了解!
  • 在 GitHub 上的一个回答中,有人提到这是 Mongoose 的问题,通过增加 poolSize 值,您可以摆脱这个错误。在我的情况下,将运行超过 1000 个查询,每次调用 lastStep 函数时,都会发生 2 件事。 11 它会更新电子邮件数据,它会检查列表中的所有电子邮件是否完成,如果是,它将更新列表状态。这对排队的过程有影响吗?
  • 是的,上面的代码重复了这个工作,但是通过使用 removeRepeatable 你可以在第一次成功时停止重复,也可以结合 removeOnComplete 和 removeOnFail 你可以使它更健壮。即使有大量文档,我也在努力消化牛市。如果有帮助,请放弃答案。
  • 看看这个仓库:github.com/DheemanthBhat/bull-lib
  • 当然可以。我会试试看,然后回复你!
猜你喜欢
  • 2022-08-06
  • 1970-01-01
  • 2014-11-19
  • 1970-01-01
  • 2019-07-10
  • 2018-09-27
  • 2018-08-16
  • 2017-02-23
  • 2012-08-22
相关资源
最近更新 更多