我想制作一个可以使用 kill 命令正常关闭的 ruby 守护进程。
我想添加一个信号陷阱,它会等到 #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 脚本而不是将其作为守护程序代码的一部分?就像 monit
或 God
会打电话来阻止它一样?
我很感激任何建议。
最佳答案
你可以像这样捕获中断
:
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
,所以几乎总是会有延迟,直到进程在您杀死它之后停止。您可能可以通过突然休眠或结合使用各种变体(在 sleep
或其他东西周围拯救 Interrupt
)来解决这个问题。
关于干净关闭的 Ruby 守护进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5793543/