我使用 Rufus-Scheduler DaemonKit守护Ruby调度程序脚本(使用Rufus),我试图捕获TERM或INT信号,让应用程序在退出前尝试保存状态。
DaemonKit有自己的trap_state(私有)方法,它会在守护进程脚本之前捕获信号,所以即使我有这个块,它也不会做太多。
DaemonKit::Application.running! do |config|
surprise = Surprise.new(interval, frequency, false)
surprise.start
config.trap( 'SIGINT' ) do #tried INT and TERM as well
puts 'Exiting'
surprise.stop
File.delete($lock)
end
end
作为副作用(可能是我的实现中的错误?)在sigterm之后.rufus锁定文件仍然存在
现在ctrl-c上的行为就是这个
[daemon-kit]: DaemonKit (0.3.1) booted, now running surprise
log writing failed. can't be called from trap context
[daemon-kit]: Running signal traps for INT
log writing failed. can't be called from trap context
[daemon-kit]: Running shutdown hooks
log writing failed. can't be called from trap context
[daemon-kit]: Shutting down surprise
启动方法是一个非常简单的计划
def start
@scheduler = Rufus::Scheduler.new(:lockfile => $lock)
@scheduler.every '1d', :first_at => @first, :overlap => false do |job|
... # some work
end
@scheduler.join
end
def stop
# save state
@scheduler.shutdown
end
答案 0 :(得分:2)
查看您自己的答案,以及您粘贴的以下代码:
def start
@scheduler = Rufus::Scheduler.new(:lockfile => $lock)
# ...
@scheduler.join # <- NOT NEEDED
end
DaemonKit的DaemonKit::Application.running!
块实际上从未完成运行,因此您可以安全地跳过在任何线程上调用#join
。
我们应该努力使这个用例更加清晰,我希望看到它更广泛地用于这种工作。
答案 1 :(得分:1)
所以它非常简单,我需要在start方法中运行调度程序之前配置陷阱proc(或我的情况下的块)。现在感觉不是很聪明,但是下面的代码按预期工作。作为参考,set_trap在DK中是私有的,但公共陷阱方法会覆盖DK启动时的默认值。
DaemonKit::Application.running! do |config|
surprise = Surprise.new(interval, frequency, false)
config.trap("TERM") { surprise.stop }
config.trap( "INT" ) { surprise.stop }
surprise.start
end
有趣的是,我在启动时看到了这条线,我之前没有注意到
[daemon-kit]: Trapping SIGINT signals not supported on this platform
INT和TERM都可以工作