铁路定期任务

时间:2012-11-12 23:07:40

标签: ruby-on-rails ruby asynchronous scheduled-tasks

我在rails应用程序上有一个ruby,我试图找到一种方法来每隔几秒运行一些代码。

我发现了许多使用cron或类似cron的实现的信息和想法,但这些只是精确到一分钟,和/或需要外部工具。我希望每15秒左右关闭一次任务,我希望它完全自包含在应用程序中(如果应用程序停止,任务停止,没有外部设置)。

这用于缓存数据的后台生成。每隔几秒,任务将汇总一些数据,然后将其存储在缓存中,该缓存将被所有客户端请求使用。任务很慢,因此需要在后台运行而不是阻止客户端请求。

我对ruby很新,但是有一个强大的perl背景,而我解决这个问题的方法就是创建一个间隔计时器&处理程序,它会分叉,运行代码,然后在完成后退出 仅模拟客户端请求并让rails控制器自行分配可能更好。这样我可以通过点击它来启动任务(虽然任务将每隔几秒运行一次,我怀疑我将需要,但可能有将来使用)。虽然让控制器调用周期性任务调度程序调用的任何方法(一旦我有一个),这是微不足道的。

6 个答案:

答案 0 :(得分:11)

我建议凡是gem https://github.com/javan/whenever

它允许您指定如下的计划:

every 15.minutes do
  MyClass.do_stuff
end

没有安排cron工作或使用外部服务进行调整。

答案 1 :(得分:2)

一般来说,我不知道在应用程序中创建周期性任务的内置方式。 Rails是在Rack上构建的,它希望接收http请求,做某事,然后返回。所以你只需要自己在外部管理周期性任务。

我认为考虑到运行任务所需的频率,一个不错的解决方案可能只是为自己写一个简单的rake任务,它永远循环,并在你启动应用程序的同时启动它,使用某些东西像福尔曼一样。 Foreman经常被用来管理启动/关闭后台工作人员及其应用程序。在制作时,您可能希望使用其他东西来管理流程,例如Monit。

答案 2 :(得分:2)

您可以编写自己的方法,例如

class MyWorker
  def self.work
    #do you work
    sleep 15
  end
end

使用rails runner MyWorker.work运行它 将在后台运行一个单独的进程

或者您可以使用像Resque这样的东西,但这是一种不同的方法。它的工作方式是这样的:有些东西会向队列添加一个任务,同时一个worker正在获取它在队列中的任何工作,并尝试完成它。

所以这取决于你自己的需要。

答案 3 :(得分:1)

我知道这是一个老问题。但也许对某人来说这个答案可能会有所帮助。有一个名为crono的宝石。

  

Crono是Ruby on Rails的基于时间的后台作业调度程序守护程序(就像Cron一样)。

     

Crono是纯Ruby。它不使用Unix Cron和其他依赖于平台的东西。因此,您可以在Ruby支持的所有平台上使用它。它使用Active Record将作业状态保留到您的数据库。您可以完全控制执行流程的作业。它是Ruby,因此您可以理解并修改它以满足您的需求。

crono令人敬畏的是它的代码是自我解释的。为了定期执行任务,您可以执行以下操作:

Crono.perform(YourJob).every 2.days

也许你也可以这样做:

Crono.perform(YourJob).every 30.seconds

无论如何,你真的可以做很多事情。另一个例子可能是:

Crono.perform(TestJob).every 1.week, on: :monday, at: "15:30"

我建议使用此gem而不是whenever因为每次使用的Unix Cron表都不可用。

答案 4 :(得分:0)

使用类似延迟工作的东西,并经常重新排队?

答案 5 :(得分:0)

使用使用eventmachine的瘦服务器或其他服务器,然后只使用属于eventmachine的计时器。示例:在config / application.rb

EM.add_periodic_timer(2) do
  do_this_every_2_sec
end