Rufus Scheduler vs Loop with Sleep

Rufus Scheduler vs Loop with Sleep

我需要在我的 Rails 5 应用程序中 运行 一个 ActiveJob 尽可能频繁。

到目前为止,我一直在使用使用 whenever gem 定义的 cron 作业(过去使用 Crono)。

这种方法会在执行操作之前启动整个 rails 应用程序,然后关闭并重新执行。我希望避免它,而是有一个持久的 "service" 来完成这项工作。

我偶然发现了 Rufus Scheduler gem 这看起来不错,但后来我开始怀疑我是否需要它。

那么,我的问题是:

下面这两个选项之间是否存在任何有意义的差异:

# With Rufus
scheduler = Rufus::Scheduler.new
scheduler.every('1s') { puts 'hello' }
scheduler.join

# Without Rufus
loop { puts "hello" ; sleep 1 }

请注意,这些脚本中的任何一个都将作为 docker 容器与 rails runner my_scheduler.rb 一起执行,并且任何解决方案都必须确保作业 运行 仅执行一次(绝不能同时执行两个) .

有区别。

Rufus-scheduler every 将尝试每 1 秒 运行,因此在 t0 + 1、t0 + 2、t0 + 3 等。而 "sleep" 变体将 运行 在 t0,t0 + wt1 + 1,t0 + wt1 + 1 + wt2 + 1,...(其中 wtN = puts hello 第 N 次调用的工作时间)。

Rufus-scheduler every 将使用 rufus-scheduler 工作线程,因此如果存在重叠 (wt(Nb) > wt(Na)),Nb 无论如何都会发生。此行为可以更改(请参阅 job options)。

Rufus-scheduler interval 更接近您的睡眠选项:

scheduler.interval('1s') { puts 'hello' }

它在 puts 'hello' 的每个 运行 之间放置 1 秒(或您想要的任何时间间隔)。

对于简单的睡眠循环,我会选择睡眠选项。但如果你需要更多,rufus-scheduler 有 cronintervalevery 和调整选项。您可以安排多个作业。

scheduler.cron('0 1 1 * *') do
  # every first of the month at 1am
  flush_archive
end
scheduler.cron('0 8,13,19 * * mon-fri') do
  # every weekday at 8am, 1pm, 7pm
  clean_dishes
end
scheduler.interval('1s') do
  puts 'hello'
end