2014-10-09 5 views
1

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

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 файл блокировки еще есть

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

Извините, но в rufus-scheduler нет никакой ловушки 3.x (rufus-scheduler 2.x имел один, но ограничивался его специальной реализацией SignalScheduler). Вы уверены, что ваша строка 'File.delete ($ lock)' достигнута? Вы уверены, что это удастся, если оно будет достигнуто? Поместите 'puts 'Exited'' в конце вашей ловушки ... Волшебное фехтование. – jmettraux

+1

@jmettraux ugh Я глуп, я перепутал DaemonKit и Rufus. Это DaemonKit trapping TERM, мой плохой – blackbird

+0

Пожалуйста, обновите свои объяснения. Заранее спасибо! – jmettraux

ответ

1

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

+0

Я вижу, что в 'Surprise # start' вы вызываете' Scheduler # join', который блокирует текущий код, и следующие ловушки никогда не были установлены. Вот почему в этой версии он работает. –

2

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

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

DaemonKit::Application.running! блок DaemonKit фактически никогда не заканчивается Runnin g, чтобы вы могли спокойно пропустить вызов #join в любом потоке.

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

+0

Спасибо! Это может быть проблемой, когда я использовал Rufus самостоятельно перед DK. Когда мне нужно будет присоединиться к нитям? – blackbird

+0

В проекте Vanilla Ruby вам нужно будет это сделать. DaemonKit абстрагирует необходимость сохранения вашего сценария. С помощью крючка или мошенника держите свой процесс в живых и запущенном. –