2009-02-13 146 views
3

在我的Rails應用程序中,我有一個更新數據庫中某些記錄的腳本。當我發送一個SIGTERM來終止腳本時,它偶爾會在ActiveRecord執行查詢時收到該信號。這導致引發ActiveRecord :: StatementInvalid異常。進程收到SIGTERM時ActiveRecord :: StatementInvalid?

我想趕上時,他們他們是一個SIGTERM的結果,並退出腳本發生StatementInvalid例外。我如何知道由於信號而導致StatementInvalid出現而不是出於其他原因?

+0

是否還有其他的東西你想要關閉這個問題? – wuputah 2010-08-25 19:48:52

回答

0

這聽起來像這個「劇本」是外部Rails應用程序(script/runner或相似?),所以也許你可以斷開的「信號處理器」和「工人」?例如,你可以派生一個子進程/線程/光纖/ ...來做數據庫更新,併發信號通知父母指示「立即停止」?當然,家長必須「發信號」讓孩子停止使用一些適當的機制(不是SIGTERM ;-))。

5

如果你陷入TERM信號,我相信你會避免這個例外。您可以在腳本的開頭執行此操作(或者在任何地方執行此操作,但只需執行一次操作)。

Signal.trap("TERM") do 
    Kernel.exit! 
end 

你得到StatementInvalid錯誤的原因是Ruby通過在當前執行的地方引發一個SIGTERM異常來處理信號。 ActiveRecord捕獲異常並將其重新拋出爲StatementInvalid。通過設置Signal處理程序,Ruby將執行您的處理程序,而不是引發異常。

更多信息,請參見Ruby Signal documentation

+0

修正了,一定要用Kernel.exit!爲此工作。通過示例驗證:http://gist.github.com/66735 – wuputah 2009-02-19 05:03:45

0

這不是一個確切的答案,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 
相關問題