我即将在工作中使用带有 upstart export 的工头来开始一些无限的rake任务。
我谦虚的“守护进程”就像这样简单:
task magic: :environment do
loop do
make_stuff_happen
sleep 10
end
end
我想知道工头是否在被要求重启时不会直接杀死进程(例如capistrano deploy),因为我不希望因此而发生任何损坏的操作。
如果是这样,如何预防?
答案 0 :(得分:5)
如果您执行导出,则可能在配置上有app-jekyll-1.conf
这样的文件
其中包含类似的东西
start on starting app-jekyll
stop on stopping app-jekyll
respawn
exec su - username -c 'cd /some/directory; export PORT=5000; bundle exec jekyll serve -w >> /tmp/a pp.log/jekyll-1.log 2>&1'
这基本上是ubuntu upstart的配置。
现在,当您使用upstart重新启动服务时,它实际上会调用initctl restart
http://upstart.ubuntu.com/cookbook/#restart
调用initctl restart
会将SIGTERM信号发送到作业
https://serverfault.com/questions/189780/what-signal-does-upstart-initctl-use-to-restart-a-job
现在清理资源取决于程序在收到SIGTERM信号时是否进行清理。
当你要求重启时,工头是否会杀死rake进程的问题 答案是是它会通过将SIGTERM发送到rake进程来终止进程。
默认情况下,当rake收到SIGTEM时,它将退出该进程。
例如,如果这是你的Rakefile
def do_some_magic
puts "doing some magic.."
sleep 5
end
task :magic do
puts "Running the task wit PID #{$$}"
loop do
do_some_magic
sleep 5
end
end
然后如果你运行它
$ rake magic
Running the task wit PID 29527
doing some magic..
在单独终端上,您可以使用给定的PID将SIGTERM发送到rake进程。它会引发异常
$ kill 29527
在上一个终端上你会得到
...
doing some magic..
rake aborted!
SIGTERM
/tmp/foo/Rakefile:11:in `sleep'
/tmp/foo/Rakefile:11:in `block (2 levels) in <top (required)>'
/tmp/foo/Rakefile:8:in `loop'
/tmp/foo/Rakefile:8:in `block in <top (required)>'
Tasks: TOP => magic
(See full trace by running task with --trace)
所以这基本上是耙死了。它会立即阻止一切。如果do_some_magic
当前正在执行数据库操作,则可能会保持不一致状态。
您当然可以处理此信号以执行一些清理工作。
如果您想等到do_some_magic
完成
def do_some_magic
puts "doing some magic.."
sleep 5
end
task :magic do
puts "Running the task wit PID #{$$}"
loop do
do_some_magic
if $shutdown
puts "shutting down..., exiting loop"
break
end
end
end
trap "TERM" do
puts "SIG TERM received."
$shutdown = true
end
再次运行它..
$ rake magic
Running the task wit PID 30150
doing some magic..
并且在分离器终端上再次使用pid杀死进程
$ kill 30150
在您之前的终端上,该过程将是这样的
....
doing some magic..
SIG TERM received.
shutting down..., exiting loop
<强>结论强>
希望有所帮助