Ruby守护进程,干净关闭

时间:2011-04-26 16:42:11

标签: ruby daemon

我想创建一个ruby守护进程,它可以使用kill命令正常关闭。 我想添加一个信号陷阱,它会等到#code that could take some time to run完成才能关闭。我如何将其添加到以下内容中:

pid = fork do
   pid_file = "/tmp/pids/daemon6.pid"
   File.open(pid, 'w'){ |f| f.write(Process.pid) }
   loop do
      begin
         #code that could take some time to run
      rescue Exception => e
         Notifier.deliver_daemon_rescued_notification(e)
      end
      sleep(10)
   end
end
Process.detach pid

另外,将它放在一个单独的脚本中会更好吗,比如单独的kill脚本而不是将它作为守护程序代码的一部分?像monitGod会要求停止它?

我感谢任何建议。

1 个答案:

答案 0 :(得分:7)

您可以抓住Interrupt,如下所示:

pid = fork do
  begin
    loop do
      # do your thing
      sleep(10)
    end
  rescue Interrupt => e
    # clean up
  end
end
Process.detach(pid)

您可以对Signal.trap('INT') { ... }执行相同操作,但如果涉及sleep,我认为捕获异常会更容易。

更新:这是一种更传统的方式,它可以确保循环在停止之前始终完成:

pid = fork do
  stop = false
  Signal.trap('INT') { stop = true }
  until stop
    # do your thing
    sleep(10)
  end
end

缺点是它始终会执行sleep,所以几乎总会有一个延迟,直到你杀死它后该过程停止。你可以通过突然睡觉或组合变体(在Interrupt或其他地方周围拯救sleep)来解决这个问题。