首页 文章

优雅地停止heroku工作者的rufus调度程序

提问于
浏览
1

我在一个在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 .

附:不,我不能使用heroku调度程序,因为我需要每分钟运行这个任务;-) .

EDIT (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,它优雅地关闭 .

2 回答

  • 1

    好的,它是Ruby 2.0特定的(https://www.ruby-forum.com/topic/4411227

    rufus-scheduler的下一个版本将包含一个变通方法 .

    https://github.com/jmettraux/rufus-scheduler/issues/98

    感谢您报告此问题 .

  • 1

    您遇到的问题是由于 trap 中的 Thread 同步造成的 . 我会这样解决它:

    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
    

    抽壳:

    $ ruby exit_scheduler.rb
    "2.0.0-p0"
    60580
    

    shell2:

    $ kill -s TERM 60580
    

    抽壳:

    :bye
    

相关问题