2014-10-09 66 views
1

我使用Rufus-Scheduler守護了一個Ruby調度程序腳本(使用Rufus) 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)'行已經到達嗎?你確定它會成功,如果達到?在你的陷阱的末端放置一個'放置'退出'...狼擊劍。 – jmettraux 2014-10-09 21:15:32

+1

@jmettraux呃我很笨,我把DaemonKit和Rufus混在一起。它是DaemonKit陷印TERM,我的不好 – blackbird 2014-10-10 01:56:35

+0

請更新你的解釋。提前致謝! – jmettraux 2014-10-10 01:59:39

回答

1

所以這很簡單,我需要配置th e trap過程(或阻止我的情況)之前,我在啓動方法中運行調度程序。現在感覺不太聰明,但下面的代碼按預期工作。作爲參考,在DK中set_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 

有趣的是,我看到在啓動這條線,雖然

+0

我在'驚喜#開始'中看到了'Scheduler#join',它阻止了正在運行的代碼,並且從未設置過以下陷阱。這就是爲什麼在這個版本中它起作用。 – 2014-10-10 11:30:55

2

看你自己的答案。我以前沒有

[daemon-kit]: Trapping SIGINT signals not supported on this platform 

INT和期限都工作注意到了,下面的代碼粘貼到你:

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

DaemonKit的DaemonKit::Application.running! block實際上從來沒有完成runnin g,所以你可以安全地跳過在任何線程上調用#join

我們應該努力使這個用例更清楚,因爲我希望看到它在這種有點工作中被廣泛使用。

+0

謝謝!當我在DK之前獨自使用Rufus時,這可能是一個剩餘物。我什麼時候需要加入這些線程? – blackbird 2014-10-10 14:01:18

+0

在一個vanilla Ruby項目中,您需要這樣做。 DaemonKit提取了保持腳本的需要。它會通過鉤子或騙子讓你的進程保持運行。 – 2014-10-13 07:02:59