首页 > 解决方案 > `agenda.js` 如何计算`every()` 操作的时区

问题描述

agenda.js在我的 Node 项目中使用,支持 MongoDB 数据库,来处理我们需要运行的批处理过程。这运作良好。但是,我确实对时区有疑问。当我使用该every()操作时,它似乎接受了作业名称和时间表。所以我一直在为数据库播种工作,如下所示:

  for (let job of dbJobs) {
    await agenda.every(schedule, job.name);
  }

请注意,对于上述内容,schedule是 cron 格式 -- 00 05 * * 1-5

这行得通。但是,据我所知,every()不接受repeatTimezone. 那么在这些情况下如何计算时区呢?

澄清一下,当我在使用 添加作业后查看数据库中的文档时every(),该repeatTimezone属性存在,但其值设置为null

其他agenda操作,如repeatEvery()确实接受时区参数,如下所示:

job.repeatEvery('0 6 * * *', {
  timezone: 'America/New_York'
});

自从我使用 以来every(),我一直通过首先使用 为数据库播种every(),然后运行 ​​MongoupdateMany()将 timzeone 显式添加到所有作业中来管理它:

async function addTimezoneToJobs() {
  try {
    const db = await client.db(dbName);
    await db.collection('batch_processes').updateMany({}, {
      $set: {
        repeatTimezone: 'America/New_York'
      }
    });
  } catch (error) {
    console.log(error);
  }
}

但奇怪的是,agenda即使我没有像我那样明确地将repeatTimezone属性值添加到作业中,它似乎也计算了相同的时间。

我不明白这里发生了什么?运行时间是如何计算的every(),有没有办法传入时区?

仅供参考:我与需要在数据库中设置的时区不在同一个时区。

标签: node.jsmongodbagenda

解决方案


您的问题似乎是 2 部分,我不确定我能否很好地解释它,但让我试试

所以,你的第一个问题

但是,据我所知,every()不接受时区的论点

好吧,从技术上讲,您也可以添加Timezone选项,every()因为此方法的作用是在job.repeatEvery内部调用,并且您已经知道可以添加选项timezone。为了支持我的回答,我找到了 2 个证据

  1. 文档asevery接受 4 个参数

每(间隔,名称,[数据],[选项])

options是一个可选参数,将传递给job.repeatEvery. 为了使用此参数,还必须指定数据。

因此,如果您也通过了,您在技术上也可以通过timezonedata

  1. SourceCode,您可以在这里看到它们在job.repeatEvery(interval, options)内部使用。

现在,你的第二个问题

在这些情况下计算时区有什么作用?

好吧,他们有一个非常独特但需要的模块,名为ComputeNextRunAt()

所以我浏览了他们的源代码,并发现这是为了根据startingTime和Interval计算你的工作下一次运行的时间。

您的代码有效,因为您在工作中曾(最初)提到要遵循America/New_York时区,因此每个下一个工作间隔都是基于此计算的,这就是您不需要再次指定它的原因。

因此,如果最初您没有指定 timezone 属性,您会得到您的local Timezone,但现在您这样做了,它会根据该属性计算下一个间隔。


推荐阅读