如何定义用户申请某个职位的频率?

发布于 2024-11-29 01:29:43 字数 581 浏览 0 评论 0原文

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

最坏的情况中,他们必须选择:

  • 每周、
  • 每天、
  • 每 12 小时、
  • 每 6 小时、
  • 每小时

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

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

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

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

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

I have an application that has to launch jobs repeatingly. But (yes, that would have been to easy without a but...) I would like users to define their backup frequency in application.

In worst case, they would have to choose between :

  • weekly,
  • daily,
  • every 12 hours,
  • every 6 hours,
  • hourly

In best case, they should be able to use crontab expressions (see documentation for example)

How to do this? Do I launch a job every minutes that check for last execution time, frequency and then launches another job if needed? Do I create a sort of queue that will be executed by a masterjob?

Any clues, ideas, opinions, best pratices, experiences are welcome!

EDIT : Solved this problem using Akka scheduler. Ok, this is a technical solution not a design answer but still everything works great.

Each user defined repetition is an actor that send messages every period to a new actor to execute the actual job.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无言温柔 2024-12-06 01:29:43

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

如果您只能使用 Play:

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

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

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

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

There may be two ways to do this depending on your requirements/architecture:

If you can only use Play:

  • The user creates the job and the frequency it will run (crontab, whatever).
  • On saving the job, you calculate the first time it will have to be run. You then add an entry to a table JOBS with the execution time, job id, and any other information required. This is required as Play is stateless and information must be stored in the DB for later retrieval.
  • You have a job that queries the table for entries whose execution date is less than now. Retrieves the first, runs it, removes it from the table and adds a new entry for next execution. You should keep some execution counter so if a task fails (which means the entry is not removed from DB) it won't block execution of the other tasks by the job trying again and again.
  • The frequency of this job is set to run every second. That way while there is information in the table, you should execute the request around as often as they are required. As Play won't spawn a new job while the current one is working if you have enough tasks this one job will serve all. If not, it will be killed at some point and restored when required.

Of course, the crons of the users will not be too precise, as you have to account for you own cron delays plus execution delays on all the tasks in queue, which will be run sequentially. Not the best approach, unless you somehow disallow crons which run every second or more often than every minute (to be safe). Doing a check on execution time of the crons to kill them if they are over a certain amount of time would be a good idea.

If you can use more than Play:

The better alternative I believe is to use Quartz (see this) to create a future execution when the user creates the job, and reproram it once the execution is over.

森林很绿却致人迷途 2024-12-06 01:29:43

谷歌群组上对此进行了讨论。据我记得,您必须定义一个每 6 小时启动一次的作业,并检查必须完成哪些备份。因此,您必须记住上次备份作业何时完成并自己进行控制。我不确定 Quartz 是否可以满足这样的要求。

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

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

There was a discussion on google-groups about it. As far as I remember you must define a job which start every 6 hours and check which backups must be done. So you must remember when the last backup job was finished and make the control yourself. I'm unsure if Quartz can handle such a requirement.

I looked in the source-code (always a good source ;-)) and found a method every, where I think this should be do what you want. How ever I'm unsure if this is a clever design, because if you have 1000 user you will have then 1000 Jobs. I'm unsure if Play was build to handle such a large number of jobs.

[Update] For cron-expressions you should have a look into JobPlugin.scheduleForCRON()

成熟的代价 2024-12-06 01:29:43

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

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

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

There are several ways to solve this.

If you don't have a really huge load of jobs, I'd just persist them to a table using the required flexibility. Then check all of them every hour (or the lowest interval you support) and run those eligible. Simple.

Or, if you prefer to use cron syntax anyway, just write (export) jobs to a user crontab using a wrapper which calls back to your running app, or starts the job in a standalone process if that's possible.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文