Руфус-планировщик, 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 в любой теме.

Мы должны поработать над тем, чтобы сделать этот вариант использования более понятным, так как я хотел бы, чтобы он использовался более широко для такой работы.

Другие вопросы по тегам