我想向rails应用程序添加类似于“后台”线程的东西。我需要不时地检查电子邮件(假设每10分钟),然后根据电子邮件做一些事情。这应该与bug追踪器的工作方式相同,您可以回复从bug追踪器收到的电子邮件,它会接收该电子邮件并将其添加到工单中。
有没有什么简单的方法可以在后台运行这样的东西?我不想使用cron或任何系统工具,只想使用纯ruby。我开始申请,我不应该关心其他任何事情。
发布于 2012-06-01 22:25:39
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的工具。
发布于 2013-07-26 07:57:18
对于公认的答案,有几个潜在的问题值得指出。
首先,PeriodicTimer
使用尾递归重新调度自己以供执行,即在执行其块之后调用EventMachine.add_timer
。不幸的是,代码不使用begin-ensure-end
,这意味着如果您的代码中有异常,计时器将停止。参见GH#454。
第二,EventMachine
的反应器循环作为单例在单线程中运行的问题。如果你启动一个PeriodicTimer
并在它的块中执行缓慢的电子邮件操作,你将阻塞反应器循环,其他代码可能依赖它。更好的方法是使用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
发布于 2012-06-01 22:30:01
查看Daemon-Kit。它允许您在框架中创建Ruby Daemons,其约定与Rails的项目类似。我们使用它来监视和执行各种后台任务。
https://stackoverflow.com/questions/10851996
复制相似问题