修改现有的,时区初始的调度程序来处理夏令时?

时间:2015-03-16 22:13:39

标签: python-2.7 datetime

我们目前在纯python中有一个不知道时区的调度程序。

它使用有序事件的heapq(python二进制堆),包含回调的时间,回调和参数。它从heapq获取最少值的时间,计算事件发生前的秒数,并在运行作业之前休眠该秒数。

我们不必担心计算机被暂停;这是在专用服务器上运行,而不是笔记本电脑。

我们希望让调度程序能够很好地应对时区变化,所以我们在11月份没有问题,就像我们最近做的那样(我们有一项重要的工作需要在数据库中进行调整才能使其运行上午8:15而不是上午9:15 - 通常在上午8:15运行。我想我们可以:

  1. 以UTC格式存储所有时间。
  2. 让调度程序休眠1分钟,然后循环测试,重新计算 每次“现在”,并且与作业日期时间进行< =比较。
  3. 工作比一小时更频繁地运行应该“正常运行”。
  4. 在凌晨2:00到凌晨2:59(含)之间的每小时工作 时间更改日,可能应该跳过一小时的PST-> PDT,然后运行 PDT-> PST的额外时间。
  5. 乔布斯运行时间不到一小时,可能应该避免重新运行 在有时间变化的日子里的情况。
  6. 这听起来是对的吗?它可能在哪里?

    谢谢!

1 个答案:

答案 0 :(得分:1)

我之前曾就其他编程语言编写了几次调度问题。这些概念对python也有效。您可能希望阅读其中一些帖子:123456

我将尝试从Python的角度再次解决具体问题:

  • 将重复发生模式与执行时间分开是很重要的。重复发生模式应该存储用户输入时间的时间,通常是本地时间。即使重复发生模式只是一次",它仍然应该存储为本地时间。调度是少数几个使用案例中的一个,其中"的常见建议始终在UTC" 中不起作用!

  • 您还需要存储时区标识符。这些应为IANA时区,例如America/Los_AngelesEurope/London。在Python中,您可以使用pytz库来处理这些时区。

  • 执行时间应该基于UTC。任何事件的 next 执行时间应根据重复模式中的本地时间计算。您可能希望提前计算并存储这些执行时间,以便您可以轻松确定要运行的下一个事件。

  • 您应该准备重新计算这些执行时间。您可能希望定期执行此操作,但至少应在将时区更新应用于系统时执行此操作。您可以(并且应该)订阅tz update announcements from IANA,然后查找相应的pytz updates on pypi

    这样想。当您将本地时间转换为UTC时,您假设您知道该时间点的时区规则,但 nobody 可以预测什么政府将来会这样做。时区规则可以改变,而且他们经常这样做。你需要考虑到这一点。

  • 您应该测试无效和模糊的时间,并制定处理它们的计划。这些在安排时很容易被击中,特别是对于重复发生的事件。

    例如,您可以安排任务在每天凌晨2:00运行 - 但是在春季转发当天,该时间不存在。那你该怎么办?在许多情况下,您希望在当天凌晨3:00运行,因为它是在1:59 AM之后的下一次。但在某些(更罕见的)情境中,您可能会在凌晨1点或凌晨1点59分运行,或者完全跳过那一天。

    同样,您可以安排任务在每天凌晨1:00运行,但在回退过渡当天,凌晨1:00发生两次。所以你会怎么做?在许多情况下,第一个实例(即 daylight 实例)是正确的触发时间。在其他(更罕见的)情况下,第二个实例可能更合适,或者(甚至更罕见)实际运行两次作业可能是合适的。

关于以every X [hours/minutes/seconds]类型计划运行的作业:

  • 这些最容易按UTC安排,不应受DST更改的影响。

  • 如果这些是您正在运行的类型的作业,您可以将整个系统基于UTC。但是,如果您正在运行不同类型的工作,那么您可以考虑只设置"本地时区"成为" UTC"在重现模式中。

  • 或者,您可以按真正的本地时间安排它们,只需确保在作业运行时根据当前执行时间计算下一个执行时间,该时间应该已经是UTC。

  • 您不应该区分超过每小时运行的作业或运行时间少于每小时的作业。我希望在回退过渡当天每小时运行25次,在春季前进过渡当天运行23次。

关于你的睡眠计划和每分钟唤醒一次 - 这可能会工作,只要你没有处理亚分钟任务。但它可能不一定是处理它的最有效方式。如果正确预先计算并存储执行时间,则可以将单个任务设置为在下次运行时唤醒,运行需要运行的所有内容,然后为下一个执行时间设置新任务。你不必每分钟醒来一次。

您还应该考虑运行预定作业所需的资源。如果您安排所有需要在午夜运行的1000个任务,会发生什么?好吧,他们不一定能够在一台计算机上同时运行。您可以将它们排队以便批量运行,或将负载分散到不同的时间段。在云环境中,您可能会启动其他工作人员来处理负载。