具有干净关闭功能的 Ruby 守护进程

发布于 2024-11-03 10:40:31 字数 600 浏览 3 评论 0原文

我想制作一个 ruby​​ 守护进程,可以使用kill命令正常关闭。 我想添加一个信号陷阱,它会等到 #code that might take some time to run 完成后再关闭。我如何将其添加到这样的内容中:

pid = fork do
   pid_file = "/tmp/pids/daemon6.pid"
   File.open(pid, 'w'){ |f| f.write(Process.pid) }
   loop do
      begin
         #code that could take some time to run
      rescue Exception => e
         Notifier.deliver_daemon_rescued_notification(e)
      end
      sleep(10)
   end
end
Process.detach pid

另外,将其放在单独的脚本中(例如单独的终止脚本)而不是将其作为守护程序代码的一部分会更好吗?就像 monitGod 会调用来阻止它一样?

我很感激任何建议。

I would like to make a ruby daemon that would gracefully shutdown with a kill command.
I would like to add a signal trap that would wait until #code that could take some time to run finishes before shutting down. How would I add that to something like this:

pid = fork do
   pid_file = "/tmp/pids/daemon6.pid"
   File.open(pid, 'w'){ |f| f.write(Process.pid) }
   loop do
      begin
         #code that could take some time to run
      rescue Exception => e
         Notifier.deliver_daemon_rescued_notification(e)
      end
      sleep(10)
   end
end
Process.detach pid

Also, would it be better to have that in a separate script, like a separate kill script instead of having it as part of the daemon code? Like something monit or God would call to stop it?

I appreciate any suggestions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

忆离笙 2024-11-10 10:40:31

您可以捕获 Interrupt,如下所示:

pid = fork do
  begin
    loop do
      # do your thing
      sleep(10)
    end
  rescue Interrupt => e
    # clean up
  end
end
Process.detach(pid)

您可以使用 Signal.trap('INT') { ... } 执行相同的操作,但使用 sleep code> 涉及我认为捕获异常更容易。

更新:这是一种更传统的方法,它确保循环在停止之前始终完成一次完整的执行:

pid = fork do
  stop = false
  Signal.trap('INT') { stop = true }
  until stop
    # do your thing
    sleep(10)
  end
end

缺点是它总是会进行睡眠,所以几乎总是会有延迟,直到进程在你杀死它后停止。您可以通过突发睡眠或组合使用各种变体(在睡眠期间挽救中断或其他方式)来解决这个问题。

You can catch Interrupt, like this:

pid = fork do
  begin
    loop do
      # do your thing
      sleep(10)
    end
  rescue Interrupt => e
    # clean up
  end
end
Process.detach(pid)

You can do the same with Signal.trap('INT') { ... }, but with sleep involved I think it's easier to catch an exception.

Update: this is a more traditional way of doing it, and it makes sure the loop always finishes a complete go before it stops:

pid = fork do
  stop = false
  Signal.trap('INT') { stop = true }
  until stop
    # do your thing
    sleep(10)
  end
end

The downside is that it will always do the sleep, so there will almost always be a delay until the process stops after you've killed it. You can probably get around that by sleeping in bursts, or doing a combination of the variants (rescuing the Interrupt just around the sleep or something).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文