Запуск фоновых задач с Capistrano
Для моего RubyOnRails-приложения мне нужно начать фоновое задание в конце развертывания Capistrano. Для этого я попробовал следующее в deploy.rb:
run "nohup #{current_path}/script/runner -e production 'Scheduler.start' &", :pty => true
Иногда это работает, но большую часть времени он не запускает процесс (= не указан в ps -aux). И сообщений об ошибках нет. И нет nohup.out, но не в домашнем каталоге, а не в каталоге приложений rails.
Я попытался использовать trap ('SIGHUP', 'IGNORE') в scheduler.rb вместо nohup, но результат тот же.
Единственный способ заставить его работать - удалить ": pty = > true" и выполнить ручную Ctrl-C в конце "развертывания крышки". Но мне это не нравится...
Есть ли еще какие-либо шансы вызвать этот Scheduler.start? Или получить еще несколько сообщений об ошибках?
Я использую Rails 2.3.2, Capistrano 2.5.8, Ubuntu Hardy на сервере
Ответы
Ответ 1
С: pty = > true, скрипты запуска пользовательской оболочки (например, bashrc и т.д.) (обычно) не загружаются. Моя рубиновая программа вышла сразу после запуска из-за отсутствия зависимых переменных среды.
Без: pty = > true, как вы описали в вопросе, 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 в файл журнала, чтобы вы могли исследовать вывод.
Ответ 2
Я хотел бы поделиться своим решением, которое также работает при выполнении нескольких команд. Я попробовал много других вариантов, найденных в Интернете, включая взлома "сна 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)
Это ответ "запускающий фоновый процесс в задаче capistrano, но хочу, чтобы другие и я могли использовать Google для этого решения.
Ответ 3
Вы хотите, чтобы ваше задание планировщика выполнялось постоянно в фоновом режиме и перезапускалось при запуске Capistrano?
Если это так, то для этого я использую runit http://smarden.sunsite.dk/runit/ и DelayedJob http://github.com/Shopify/delayed_job/tree/master
- Установить runit в режиме без замены init
- Добавьте фоновое задание в качестве службы runit и добавьте для него монитор журнала из runit.
- Попросите Capistrano вызвать sudo sv kill job_name, чтобы убить и перезапустить задание.
My backround job - это экземпляр плагина Rails DelayedJob, который обрабатывает задачи Rails. Я убиваю его при каждом развертывании Capistrano, поэтому он перезагружается с обновленной базой кода.
Это оказалось очень надежным.
НТН,
Larry
Ответ 4
Если этот планировщик задач имеет ключ -d, он будет работать. Например, автономный пассажир имеет параметр -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