1

我用Rufus-Scheduler DaemonKit守护了一个 Ruby 调度程序脚本(使用 Rufus),我试图捕获 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

start 方法是一个非常简单的时间表

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
4

2 回答 2

2

查看您自己的答案,以及您粘贴的以下代码:

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

DaemonKit 的DaemonKit::Application.running!块实际上永远不会完成运行,因此您可以安全地跳过#join对任何线程的调用。

我们应该努力使这个用例更清晰,因为我希望看到它更广泛地用于这种工作。

于 2014-10-10T11:34:50.913 回答
1

所以这很简单,我需要在启动方法中运行调度程序之前配置陷阱过程(或在我的情况下为块)。现在感觉不是很聪明,但以下代码按预期工作。作为参考,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 都可以工作

于 2014-10-10T02:26:45.507 回答