我想在rails应用程序中添加类似“后台”线程的东西。我需要不时检查电子邮件(假设每10分钟一次),然后根据电子邮件做一些事情。这应该与bug跟踪器的工作方式相同,您可以回复从错误跟踪器获得的电子邮件,它将接收电子邮件并将其添加到故障单中。
有没有简单的方法在后台运行这样的东西?我不想使用cron或任何系统工具,只是纯粹的红宝石。我开始申请,我不应该关心其他任何事情。
答案 0 :(得分:3)
EventMachine有PeriodicTimer
n = 0
timer = EventMachine::PeriodicTimer.new(5) do
puts "the time is #{Time.now}"
timer.cancel if (n+=1) > 5
end
rufus-scheduler是纯Ruby基础EventMachine中类似cron的工具。
答案 1 :(得分:1)
值得指出的接受答案有几个潜在的问题。
首先,PeriodicTimer
重新安排自己使用尾递归执行,即在执行其块后调用EventMachine.add_timer
。不幸的是,代码不使用begin-ensure-end
,这意味着如果代码中存在异常,则计时器将停止。见GH#454。
其次,EventMachine
的反应器循环在单个线程中作为单例运行的问题。如果您启动PeriodicTimer
并在其块中执行慢速电子邮件操作,您将阻止其他代码可能依赖的reactor循环。更好的方法是使用EventMachine::Deferrable
将电子邮件收集工作推送到单独的线程。有关示例,请参阅this post。
最后但并非最不重要的是,如果它的反应堆尚未运行,你应该在一个单独的线程上运行EventMachine
,但如果反应堆的线程已在运行,你应该“安排”你的工作。
把这些放在一起你有以下几点:
def check_email
timer = EM::PeriodicTimer.new(10.minutes) do
begin
DefferableEmailChecker.new.errback do |error|
# handle error
# note that this code will run OUTSIDE the
# periodic timer block
end
rescue Exception => e
# even with a Deferable this is good practice
# if you want to cancel, use timer.cancel
end
end
end
if EM.reactor_running?
EM.schedule do
check_email
end
else
Thread.new do
EM.run do
check_email
end
end
end
答案 2 :(得分:0)
结帐Daemon-Kit。它允许您在具有与Rails项目类似约定的框架中创建Ruby Daemons。我们使用它来监控和执行各种后台任务。
答案 3 :(得分:0)
我在我的项目中使用delayed_job。
Delayed_job(或DJ)封装了在后台异步执行更长任务的常见模式。