Rufus-Scheduler, DaemonKit и ловушки

Я демонизировал сценарий планировщика Ruby (используя Rufus) с помощью Rufus-Scheduler DaemonKit и пытаюсь перехватить сигналы TERM или INT, чтобы приложение пыталось сохранить состояние перед выходом.

DaemonKit имеет свой собственный метод trap_state (частный), и он перехватывает сигнал перед скриптом демона, поэтому, хотя у меня есть этот блок, он мало что делает.

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 все еще существует.

Поведение на 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

person blackbird    schedule 09.10.2014    source источник
comment
Извините, но в rufus-scheduler 3.x нет ловушки (в rufus-scheduler 2.x она была, но ограничивалась специальной реализацией SignalScheduler). Вы уверены, что ваша File.delete($lock) линия достигнута? Вы уверены, что это удастся, если оно будет достигнуто? Поместите puts 'Exited' в конец вашей ловушки... Фехтование волков.   -  person jmettraux    schedule 10.10.2014
comment
@jmettraux тьфу, я тупой, я перепутал DaemonKit и Rufus. Это DaemonKit ловит TERM, мой плохой   -  person blackbird    schedule 10.10.2014
comment
Пожалуйста, обновите свое объяснение тогда. Заранее спасибо!   -  person jmettraux    schedule 10.10.2014
comment
@jmettraux да, готово. Я тоже нашел проблему.   -  person blackbird    schedule 10.10.2014


Ответы (2)


Глядя на свой собственный ответ и следующий код, который вы вставили:

def start
  @scheduler = Rufus::Scheduler.new(:lockfile =>  $lock)
  # ...
  @scheduler.join # <- NOT NEEDED
end

Блок DaemonKit::Application.running! DaemonKit на самом деле никогда не завершает работу, поэтому вы можете спокойно пропустить вызов #join в любом потоке.

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

person Kenneth Kalmer    schedule 10.10.2014
comment
Спасибо ! Это может быть остатком, когда я использовал Rufus самостоятельно до DK. Когда мне нужно будет присоединиться к темам? - person blackbird; 10.10.2014
comment
В ванильном проекте Ruby вам нужно будет это сделать. DaemonKit избавляет от необходимости поддерживать ваш скрипт в рабочем состоянии. Это будет всеми правдами и неправдами поддерживать ваш процесс в рабочем состоянии. - person Kenneth Kalmer; 13.10.2014

Так что это очень просто, мне нужно настроить trap proc (или блок в моем случае) ДО того, как я запущу планировщик в методе запуска. Сейчас я не чувствую себя очень умным, но следующий код работает, как и ожидалось. Для справки, set_trap является приватным в DK, но общедоступный метод 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 работают, хотя

person blackbird    schedule 10.10.2014
comment
Я вижу, в Surprise#start вы вызываете Scheduler#join, который блокирует работающий код, и следующие ловушки никогда не устанавливаются. Именно поэтому в этой версии это работает. - person Kenneth Kalmer; 10.10.2014