我在一个在heroku worker上运行的rake任务中运行rufus-scheduler。我经常得到SIGTERM异常,因为常规的heroku dynos重启(参见heroku dyno docs)。我想实现上面提到的文档中显示的正常关闭,并在此过程中关闭rufus调度程序:
trap('TERM') do
scheduler.shutdown(:kill)
exit
end
但是当我尝试使用此任务将SIGTERM发送到进程时,我收到错误:
can't be called from trap context
是否有任何方法可以在SIGTERM上正常关闭rufus调度程序? 我使用ruby 2.0,rake 10.0.4,rufus-scheduler 3.0.2。
P.S。不,我不能使用heroku调度程序,因为我需要每分钟运行一次这个任务; - )。
编辑(jmettraux)
测试代码:https://gist.github.com/jmettraux/a4c00374f58e9f7affa8
Ruby 2.0.0-p247,Debian GNU / Linux上的rufus-scheduler 3.0.5产生:
/home/jmettraux/w/rufus-scheduler/lib/rufus/scheduler/job_array.rb:74:
in `synchronize': can't be called from trap context (ThreadError)
from /home/jmettraux/w/rufus-scheduler/lib/rufus/scheduler/job_array.rb:74:in `to_a'
from /home/jmettraux/w/rufus-scheduler/lib/rufus/scheduler.rb:276:in `jobs'
from /home/jmettraux/w/rufus-scheduler/lib/rufus/scheduler.rb:127:in `shutdown'
from t.rb:8:in `block in <main>'
from t.rb:18:in `call'
from t.rb:18:in `sleep'
from t.rb:18:in `<main>'
相同的平台,但使用Ruby 1.9.3-p392并且它正常关闭。
答案 0 :(得分:1)
好的,它是Ruby 2.0特定的(https://www.ruby-forum.com/topic/4411227)
下一版本的rufus-scheduler将包含一个解决方法。
https://github.com/jmettraux/rufus-scheduler/issues/98
感谢您报告此问题。
答案 1 :(得分:1)
您遇到的问题归因于Thread
中的trap
同步。我会以这种方式解决这个问题:
p "#{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}"
p $$
require 'rufus-scheduler'
s = Rufus::Scheduler.new
trap('TERM') do
$quit = true
end
s.every '10s' do
p :hello
end
s.every '1s' do
if $quit
p :bye
s.shutdown(:kill)
end
end
s.join
抽壳1:
$ ruby exit_scheduler.rb
"2.0.0-p0"
60580
shell2:
$ kill -s TERM 60580
抽壳1:
:bye