进程收到SIGTERM时ActiveRecord :: StatementInvalid?
在我的Rails应用程序中,我有一个更新数据库中某些记录的脚本。当我发送一个SIGTERM来终止脚本时,它偶尔会在ActiveRecord执行查询时收到该信号。这导致引发ActiveRecord :: StatementInvalid异常。进程收到SIGTERM时ActiveRecord :: StatementInvalid?
我想赶上时,他们他们是一个SIGTERM的结果,并退出脚本发生StatementInvalid例外。我如何知道由于信号而导致StatementInvalid出现而不是出于其他原因?
这听起来像这个“剧本”是外部Rails应用程序(script/runner
或相似?),所以也许你可以断开的“信号处理器”和“工人”?例如,你可以派生一个子进程/线程/光纤/ ...来做数据库更新,并发信号通知父母指示“立即停止”?当然,家长必须“发信号”让孩子停止使用一些适当的机制(不是SIGTERM
;-))。
如果你陷入TERM信号,我相信你会避免这个例外。您可以在脚本的开头执行此操作(或者在任何地方执行此操作,但只需执行一次操作)。
Signal.trap("TERM") do
Kernel.exit!
end
你得到StatementInvalid错误的原因是Ruby通过在当前执行的地方引发一个SIGTERM异常来处理信号。 ActiveRecord捕获异常并将其重新抛出为StatementInvalid。通过设置Signal处理程序,Ruby将执行您的处理程序,而不是引发异常。
更多信息,请参见Ruby Signal documentation。
修正了,一定要用Kernel.exit!为此工作。通过示例验证:http://gist.github.com/66735 – wuputah 2009-02-19 05:03:45
这不是一个确切的答案,OP,但是,你可以控制的出口点 - 该计划将只达到你所定义的退出点之后退出。
time_to_die=false
# Prevent abrupt stopping of the daemon.
Signal.trap("TERM") { time_to_die=true; "SIG_IGN" }
loop {
.
.
exit_gracefully if time_to_die
.
.
}
def exit_gracefully
#Cleaning up..
$log.log "#{Time.now} TERM signal received. Exiting.."
$db.close
exit
end
是否还有其他的东西你想要关闭这个问题? – wuputah 2010-08-25 19:48:52