【问题标题】:Agenda jobs, is it possible to schedule a job to be triggered after the previous one finished?议程作业,是否可以安排在前一个作业完成后触发作业?
【发布时间】:2020-09-15 20:48:25
【问题描述】:

我在 nodejs 中使用agenda jobs。我想知道是否可以定义一个具有依赖关系的工作。 就我而言,我有 3 个作业,每个作业都执行整个逻辑的一部分,这非常大,这就是它们分开的原因。

  1. 在Job 1 中,我从数据库中收集信息,对其进行转换并执行一些任务。
  2. 在Job 2 中,我获取了之前由Job 1 处理的所有数据并执行新的转换..
  3. 在Job 3 中,我再次获取了在Job 2 中处理过的所有数据并发送了一些报告。

我将这些任务安排为每 5 分钟执行一次。但问题是它们三个是同时调度的,因为它们是动态调度的。

job1.schedule("now");
job1.repeatEvery('5 minutes');

job2.schedule("now");
job2.repeatEvery('5 minutes');

job3.schedule("now");
job3.repeatEvery('5 minutes');

按照目前的配置,要处理一个需要完成 3 个作业的实例,最坏的情况是用户需要等待 15 分钟,这并不理想。

我想知道是否有一个选项来定义任务应该在前一个任务完成后立即执行。我知道一个可能的解决方法是安排具有几分钟差异的作业,但鉴于根据实例的数量,作业可能需要更多或更少的时间,这对我不起作用。

【问题讨论】:

    标签: node.js agenda


    【解决方案1】:

    我做一件非常相似的事情的方式是,当前一个作业的主要功能完成时,我触发下一个作业,这样我可以将数据从一个作业馈送到另一个作业并按顺序运行它们。

    所以我在job2的定义中触发job3,在job1的定义中触发job2:

    // DEFINE JOBS
    agenda.define('job1', (job) => {
        return myMainJob1Function(job.attrs.data)
          .then((data) => {
            for (const element of data) {
              agenda.now('job2', { // runs many instances of 'job2' job with distinct data
                // use output data from the "parent" job
                arg1: element.arg1,
                arg2: element.arg2,
                arg3: element.arg3,
                arg4: job.attrs.data.someArg, // this will propagate an argument we set for the "parent" job
              });
            }
          });
      });
    
    agenda.define('job2', (job) => {
        return myMainJob2Function(job.attrs.data) // data supplied from 'job1'
          .then((data) => {
            for (const element of data) {
              agenda.now('job3', { // runs many instances of 'job3' job with distinct data
                // use output data from the "parent" job
                arg1: element.arg1,
                arg2: element.arg2,
                arg3: element.arg3,
                arg4: job.attrs.data.someArg, // this will propagate an argument we set for the "parent" job
              });
            }
          });
      });
    
    agenda.define('job3', (job) => {
        return myMainJob3Function(job.attrs.data) // data supplied from 'job2'
          .then((data) => {
            // save data to database or do something else
          });
      });
    
    // TRIGGER 'job1', WHICH TRIGGERS CHILD JOBS
    agenda.now('job1', { someArg: 5 }); // we're providing some initial argument, that gets passed onto child jobs
    const schedule = '0 0/5 0 ? * * *' // cron expression for every 5 minutes
    agenda.every(schedule, 'job1', { someArg: 5 });
    

    想到的另一件事是为complete 或success 或job1 使用触发器,但是当您使用不同的输入数据运行许多相同的作业时,您不能(我还没有找到一种方法) 监听与您想要的特定作业实例相关的事件。

    话虽如此,你可以做到:

    agenda.on('success:job1', (job) => {
      agenda.now('job2', { someArg: job.attrs.data.someArg });
    });
    

    【讨论】:

    • 嗨,我有一个类似的问题,我想动态安排作业在不同时间运行不同的输入数据(每个作业的对象数组),但时间是相对的。例如,在第一个作业计划在 3 天后使用第一个对象中的数据运行之后,该作业应该安排在 3 天后使用数组中第二个对象中的数据再次运行 24 小时,并且下一个作业应该安排使用第三个对象中的数据在第二个作业后运行 6 小时。你知道我是怎么做到的吗?
    • @NathanielBabalola 如果我理解正确,您应该使用agenda.schedule 而不是agenda.now。见github.com/agenda/agenda#schedulewhen-name-data
    • 谢谢,但我的日程安排也有问题。我把问题贴在这里,如果你能看一下我会很高兴stackoverflow.com/questions/67527454/…
    • 我检查了你的短语输出的人工间隔 389400000 毫秒,所以它似乎工作正常。我现在没有议程项目来重现相同的行为,尤其是在没有提供示例代码的情况下。恐怕除此之外我无能为力。我不能在那里发表评论(没有足够的声誉),我没有答案,所以不会在那里发布。
    • 我使用了人工间隔,它在给定文本输入时返回毫秒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2022-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多