3

我有一个必须重复启动作业的应用程序。但是(是的,如果没有但是......)我希望用户在应用程序中定义他们的备份频率。

最坏的情况下,他们将不得不选择:

  • 每周,
  • 日常的,
  • 每12小时,
  • 每 6 小时,
  • 每小时

最好的情况下,他们应该能够使用 crontab 表达式(例如参见文档)

这个怎么做?我是否每分钟启动一项检查上次执行时间、频率的作业,然后在需要时启动另一项作业?我是否创建一种将由 masterjob 执行的队列?

欢迎任何线索,想法,意见,最佳实践,经验!

编辑:使用 Akka 调度程序解决了这个问题。好的,这是一个技术解决方案,而不是设计答案,但一切都很好。

每个用户定义的重复都是一个参与者,每个周期都向新参与者发送消息以执行实际作业。

4

3 回答 3

1

在 google-groups 上有一个关于它的讨论。据我记得,您必须定义每 6 小时启动一次的作业,并检查必须完成哪些备份。因此,您必须记住上次备份作业的完成时间并自己进行控制。我不确定 Quartz 是否可以处理这样的要求。

我查看了源代码(总是一个很好的来源;-))并找到了一种方法,我认为这应该是你想要的。我不确定这是否是一个聪明的设计,因为如果你有 1000 个用户,那么你将拥有 1000 个工作。我不确定 Play 是否是为处理如此大量的工作而构建的。

[更新] 对于 cron 表达式,你应该看看JobPlugin.scheduleForCRON()

于 2011-08-10T18:30:25.997 回答
1

根据您的要求/架构,可能有两种方法可以做到这一点:

如果您只能使用 Play:

  • 用户创建作业及其运行频率(crontab 等)。
  • 保存作业时,您计算它必须运行的第一次时间。然后,您向表 JOBS 添加一个条目,其中包含执行时间、作业 ID 和任何其他所需信息。这是必需的,因为 Play 是无状态的,并且信息必须存储在数据库中以供以后检索。
  • 您有一个作业查询表中执行日期小于现在的条目。检索第一个,运行它,从表中删除它并添加一个新条目以供下次执行。您应该保留一些执行计数器,因此如果任务失败(这意味着该条目未从 DB 中删除),它不会阻止作业一次又一次地尝试执行其他任务。
  • 该作业的频率设置为每秒运行一次。这样,虽然表中有信息,但您应该根据需要经常执行请求。因为如果你有足够的任务,当当前的工作正在工作时,Play 不会产生新的工作,这个工作将服务于所有人。如果没有,它将在某个时候被杀死并在需要时恢复。

当然,用户的 crons 不会太精确,因为您必须考虑自己的 cron 延迟加上队列中所有任务的执行延迟,这些任务将按顺序运行。不是最好的方法,除非您以某种方式禁止每秒运行一次或更频繁地运行的 crons(为了安全起见)。检查 crons 的执行时间以在超过一定时间时杀死它们将是一个好主意。

如果您可以使用的不仅仅是 Play:

我认为更好的选择是在用户创建作业时使用 Quartz(请参阅)创建未来的执行,并在执行结束后重新编程。

于 2011-08-17T14:36:09.817 回答
0

有几种方法可以解决这个问题。

如果您没有大量的工作,我会使用所需的灵活性将它们持久化到一个表中。然后每小时(或您支持的最低间隔)检查所有这些并运行那些符合条件的。简单的。

或者,如果您更喜欢使用 cron 语法,只需使用包装器将作业写入(导出)到用户 crontab,该包装器会回调您正在运行的应用程序,或者如果可能的话,在独立进程中启动作业。

于 2011-08-22T11:42:40.230 回答