我想使用流行的雷神宝石来创建一个守护进程任务。我的 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.
发布评论
评论(1)
通常管理守护进程的方法是让它们将 PID 写入文件中。这使得另一个进程可以发现守护进程的 PID,并杀死它(或发送一些其他信号)。
你的代码应该可以工作。我尝试了一个使用
deamons
gem 的简单脚本,我尝试了几次才找到了去守护进程。我认为它会得到与父进程相同的名称,或类似的名称,但它的名称是“self”。请记住,守护进程将不再写入STDOUT
。不管怎样,试试这个:
并检查
/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/framesThe 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 toSTDOUT
.Anyway, try this:
and check the
/tmp/mydaemon.pid
file for the PID. Then runps ax | grep x
where x is the PID. Runcat /tmp/mydaemon.pid
| xargs kill` to kill the daemon.I think the
daemons
' gem has some helpers for managing PidFiles, check outPidFile
in http://rubydoc.info/gems/daemons/1.1.0/frames