ActiveRecord :: StatementInvalid, когда процесс получает SIGTERM? - PullRequest
3 голосов
/ 14 февраля 2009

В моем приложении Rails у меня есть скрипт, который обновляет некоторые записи в базе данных. Когда я отправляю SIGTERM для уничтожения сценария, он иногда получает этот сигнал, когда ActiveRecord выполняет запрос. Это приводит к возникновению исключения ActiveRecord :: StatementInvalid.

Я бы хотел отловить исключения StatementInvalid, возникающие, когда они являются результатом SIGTERM, и выйти из сценария. Как я могу сказать, что StatementInvalid происходит из-за сигнала, а не по какой-то другой причине?

Ответы [ 3 ]

5 голосов
/ 16 февраля 2009

Если вы перехватите сигнал TERM, я полагаю, вы избежите исключения. Вы можете сделать это в начале вашего сценария (или, по сути, где угодно, но вам нужно сделать это только один раз).

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

Причиной возникновения ошибки StatementInvalid является то, что Ruby обрабатывает сигнал, вызывая исключение SIGTERM в месте текущего выполнения. ActiveRecord перехватывает исключение и перебрасывает его как StatementInvalid. Установив обработчик сигнала, Ruby выполнит ваш обработчик вместо того, чтобы вызывать исключение.

Подробнее см. В документации Ruby Signal .

0 голосов
/ 01 февраля 2010

Это не точный ответ ОП, однако вы можете контролировать точку выхода - программа выйдет только после достижения указанной вами точки выхода.

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
0 голосов
/ 14 февраля 2009

Похоже, этот «скрипт» является внешним по отношению к приложению Rails (script/runner или аналогичный?), Так что, возможно, вы можете разделить «обработчик сигнала» и «работник»? Например, вы можете разветвить дочерний процесс / thread / fiber / ..., чтобы выполнить обновление базы данных, и дать родителю сигнал «остановить сейчас»? Конечно, тогда родителю придется «дать понять» ребенку прекратить использовать какой-либо подходящий механизм (не SIGTERM; -)).

...