如何使用 Thor (ruby) 创建守护进程?

发布于 2024-10-11 10:21:06 字数 1129 浏览 6 评论 0 原文

我想使用流行的雷神宝石来创建一个守护进程任务。我的 Thor 类如下所示:

require 'rubygems'
require 'daemons'
require 'thor'

class CLI < Thor
  desc "start", "Startup the App"
  method_option :daemonize, :aliases => "-d", :default => false, :type => :boolean, :banner => "Run as daemon"
  def start
    run_app(options[:daemonize])
  end

  desc "stop", "Stop the daemon"
  def stop
    stop_app
  end

  no_tasks {
    def run_app(run_as_daemon)
      # Run the application code
      Daemons.daemonize if run_as_daemon
      # loop until stopped or interrupted
      # ...
    end

    def stop_app
      #stop the app
    end
  }
end

因此,我在这里设置了一个基本的 thor 类,其中包含两个任务:启动和停止。我目前也在使用 Daemons gem,但这不是必需的。我正在努力解决的部分是,当这个应用程序作为“run_thor_app.rb start”运行时,一切都运行得很好。显然,在这种情况下不需要停止任务。但是,当我运行“run_thor_app.rb start -d”时,应用程序会一直运行,直到 Daemons.daemonize 运行,然后退出。检查正在运行的进程显示后台没有任何运行。

即使有东西正在运行,我也不知道如何处理停止任务。例如,如何检测应用程序正在作为守护进程运行并停止它。我查看了 Daemons::Monitor,但文档并不清楚它是如何工作的,当我尝试它时,它不起作用。

在我看来,这对于 Thor 中内置的东西来说是一个很好的用例,但在 github 上搜索代码并没有向我透露任何信息。也许我只是在某个地方错过了它。无论如何,我认为最好记录一下使用 Thor 处理守护进程的最佳实践或模式,以供其他人参考。

I would like to use the popular Thor gem to create a daemonized task. My Thor class looks like this:

require 'rubygems'
require 'daemons'
require 'thor'

class CLI < Thor
  desc "start", "Startup the App"
  method_option :daemonize, :aliases => "-d", :default => false, :type => :boolean, :banner => "Run as daemon"
  def start
    run_app(options[:daemonize])
  end

  desc "stop", "Stop the daemon"
  def stop
    stop_app
  end

  no_tasks {
    def run_app(run_as_daemon)
      # Run the application code
      Daemons.daemonize if run_as_daemon
      # loop until stopped or interrupted
      # ...
    end

    def stop_app
      #stop the app
    end
  }
end

So here I've setup a basic thor class with two tasks, start and stop. I'm also, currently using the Daemons gem, but that isn't required. The part that I'm struggling with is that when this app runs as "run_thor_app.rb start" everything runs just fine. Obviously the stop task isn't needed in this instance. But when I run "run_thor_app.rb start -d" the app runs until Daemons.daemonize runs and then it quits. Checking the running processes shows that nothing is running in the background.

Even if something were running, I wouldn't know how to approach the stop task. For example, how do you detect that the app is running as a daemon and stop it. I've looked at Daemons::Monitor, but the documentation isn't clear on how that works and when I tried it, it didn't work.

It seems to me that this would be a good use case for something that is built into Thor, but searching through the code on github hasn't revealed anything to me. Maybe I just missed it somewhere. In any case, I think it would be good to document a best practice or a pattern for handling daemons with Thor for others to reference.

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

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

发布评论

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

评论(1

完美的未来在梦里 2024-10-18 10:21:06

通常管理守护进程的方法是让它们将 PID 写入文件中。这使得另一个进程可以发现守护进程的 PID,并杀死它(或发送一些其他信号)。

你的代码应该可以工作。我尝试了一个使用 deamons gem 的简单脚本,我尝试了几次才找到了去守护进程。我认为它会得到与父进程相同的名称,或类似的名称,但它的名称是“self”。请记住,守护进程将不再写入STDOUT

不管怎样,试试这个:

# set up everything
# then daemonize
Daemons.daemonize
# and write a pid file
File.open('/tmp/mydaemon.pid', 'w') { |f| f.puts(Process.pid) }
loop do
  # do something
  # this loop is important, if the script ends the daemon dies
end

并检查 /tmp/mydaemon.pid 文件中的 PID。然后运行 ​​ps ax | grep x 其中 x 是 PID。运行cat /tmp/mydaemon.pid | xargs Kill`​​ 来杀死守护进程。

我认为 daemons' gem 有一些用于管理 PidFiles 的帮助程序,请查看 PidFile。 0/frames" rel="nofollow">http://rubydoc.info/gems/daemons/1.1.0/frames

The way you usually manage daemon processes is by having them write their PID in a file. This makes it possible for another process to discover the daemon's PID, and kill it (or send some other signal).

Your code should work. I tried a bare bones script that used the deamons gem, and it took me a few tries until I found the deamonized process. I figured it would get the same name as the parent process, or something similar, but instead it's name was "self". Remember that the daemonized process will no longer write to STDOUT.

Anyway, try this:

# set up everything
# then daemonize
Daemons.daemonize
# and write a pid file
File.open('/tmp/mydaemon.pid', 'w') { |f| f.puts(Process.pid) }
loop do
  # do something
  # this loop is important, if the script ends the daemon dies
end

and check the /tmp/mydaemon.pid file for the PID. Then run ps ax | grep x where x is the PID. Run cat /tmp/mydaemon.pid | xargs kill` to kill the daemon.

I think the daemons' gem has some helpers for managing PidFiles, check out PidFile in http://rubydoc.info/gems/daemons/1.1.0/frames

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