对于我的RubyOnRails-App,我必须在Capistrano部署结束时开始后台工作。为此,我在deploy.rb中尝试了以下内容:
run "nohup #{current_path}/script/runner -e production 'Scheduler.start' &", :pty => true
有时候这种方法有效,但大部分时间它都没有启动过程(=未在ps -aux中列出)。并且没有错误消息。并且没有nohup.out,不在主目录中,也不在rails app目录中。
我尝试在scheduler.rb而不是nohup中使用trap('SIGHUP','IGNORE'),但结果是一样的。
让它运行的唯一方法是删除“:pty => true”并在“cap deploy”结尾处执行手动Ctrl-C。但我不喜欢这个...
还有其他机会调用此Scheduler.start吗?或者获取更多错误消息?
我在服务器上使用Rails 2.3.2,Capistrano 2.5.8,Ubuntu Hardy
答案 0 :(得分:16)
使用:pty =>是的,用户shell启动脚本(例如bashrc等)(通常)未加载。由于缺乏依赖的环境变量,我的ruby程序在启动后立即退出。
没有:pty =>是的,正如你在问题中所描述的那样,capistrano会在那里等待进程退出。您需要重定向stdout和stderr以使其立即返回。
run 'nohup ruby -e "sleep 5" &' # hangs for 5 seconds
run 'nohup ruby -e "sleep 5" > /dev/null &' # hangs for 5 seconds
run 'nohup ruby -e "sleep 5" > /dev/null 2>&1 &' # returns immediately. good.
如果您的后台任务仍未运行。尝试将stdout和stderr重定向到日志文件,以便您可以调查输出。
答案 1 :(得分:6)
我想分享我的解决方案,该解决方案在执行多个命令时也有效。我在网上尝试了很多其他的变种,包括"睡眠N"破解。
run("nohup sh -c 'cd #{release_path} && bundle exec rake task_namespace:task_name RAILS_ENV=production > ~/shared/log/<rakelog>.log &' > /dev/null 2>&1", :pty => true)
这是一个重复回复launching background process in capistrano task但想确保其他人和我自己可以谷歌寻求此解决方案。
答案 2 :(得分:1)
您是否希望Scheduler作业在后台持续运行并在运行Capistrano时重新启动?
如果是这样,那么我使用runit http://smarden.sunsite.dk/runit/和DelayedJob http://github.com/Shopify/delayed_job/tree/master
我的backround作业是Rails插件DelayedJob的一个实例,它处理后台Rails任务。我用每个Capistrano部署杀了它,所以它将使用更新的代码库重新启动。
事实证明这是非常可靠的。
HTH,
拉里
答案 3 :(得分:1)
如果此任务调度程序具有-d开关,则它将起作用。例如,passenger standalone有一个-d选项可以将其作为一个被妖魔化的进程启动。
namespace :passenger_standalone do
task :start do
run "cd #{current_path} && passenger start -e #{rails_env} -d"
end
task :stop do
run "cd #{current_path} && RAILS_ENV=#{rails_env} passenger stop"
end
task :restart do
stop
start
end
end