Руфус-планировщик, DaemonKit и ловушки
Я демонизировал скрипт планировщика Ruby (используя Rufus) с Rufus-Scheduler DaemonKit, и я пытаюсь перехватить сигналы TERM или INT, чтобы приложение попыталось сохранить состояние перед выходом.
DaemonKit имеет свой собственный метод trap_state (private), и он ловит сигнал перед сценарием демона, поэтому, даже если у меня есть этот блок, он мало что делает.
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 lockfile все еще там
Поведение на 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
2 ответа
Так что все очень просто, мне нужно настроить процедуру trap (или блокировать в моем случае) ПРЕЖДЕ ЧЕМ я запускаю планировщик в методе start. Сейчас я не очень умен, но следующий код работает, как и ожидалось. Для справки, set_trap является приватным в DK, но метод public trap переопределяет значения по умолчанию, которые приходят при запуске 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 оба работают, хотя
Глядя на свой ответ и следующий код, который вы вставили:
def start
@scheduler = Rufus::Scheduler.new(:lockfile => $lock)
# ...
@scheduler.join # <- NOT NEEDED
end
DaemonKit-х DaemonKit::Application.running!
Блок на самом деле никогда не завершает работу, так что вы можете спокойно пропустить вызов #join
в любой теме.
Мы должны поработать над тем, чтобы сделать этот вариант использования более понятным, так как я хотел бы, чтобы он использовался более широко для такой работы.