2014-10-09 49 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