使用capistrano重新启动delayed_job时,并不总是创建pid文件

时间:2012-02-27 16:51:34

标签: ruby-on-rails ruby-on-rails-3 capistrano delayed-job

当sshing进入网络服务器时,我可以整天重启delayed_job而没有任何问题。它会关闭现有的worker,启动一个新的worker并将tmp / pids / delayed_job.pid写入其进程ID。 (我也在重新启动乘客以模仿我将要使用capistrano做什么)

app@StagingServer:/app/current$ touch tmp/restart.txt; RAILS_ENV=staging script/delayed_job restart
delayed_job: trying to stop process with pid 22170...
delayed_job: process with pid 22170 successfully stopped.
delayed_job: process with pid 22284 started.
app@StagingServer:/app/current$ touch tmp/restart.txt; RAILS_ENV=staging script/delayed_job restart
delayed_job: trying to stop process with pid 22284...
delayed_job: process with pid 22284 successfully stopped.
delayed_job: process with pid 22355 started.
app@StagingServer:/app/current$ touch tmp/restart.txt; RAILS_ENV=staging script/delayed_job restart
delayed_job: trying to stop process with pid 22355...
delayed_job: process with pid 22355 successfully stopped.
delayed_job: process with pid 22427 started.
app@StagingServer:/app/current$

但是,当我使用capistrano进行部署时

dev@ubuntu:~/app-site$ cap passenger:restart
    triggering start callbacks for `passenger:restart'
  * executing `multistage:ensure'
*** Defaulting to `staging'
  * executing `staging'
  * executing `passenger:restart'
  * executing "touch /app/current/tmp/restart.txt"
    servers: ["staging.app.com"]
    [staging.app.com] executing command
    command finished in 242ms
  * executing "cd /app/current;RAILS_ENV=staging script/delayed_job restart"
    servers: ["staging.app.com"]
    [staging.app.com] executing command
 ** [out :: staging.app.com] delayed_job: trying to stop process with pid 21646...
 ** [out :: staging.app.com] delayed_job: process with pid 21646 successfully stopped.
    command finished in 11889ms
好像很好吗?虽然不打印delayed_job的最后一行(我认为由于它没有以换行结尾),但这确实成功地创建了一个新进程。但是,它不会创建.pid文件,因此当我尝试重新启动时:

dev@ubuntu:~/app-site$ cap passenger:restart
    triggering start callbacks for `passenger:restart'
  * executing `multistage:ensure'
*** Defaulting to `staging'
  * executing `staging'
  * executing `passenger:restart'
  * executing "touch /app/current/tmp/restart.txt"
    servers: ["staging.app.com"]
    [staging.app.com] executing command
    command finished in 398ms
  * executing "cd /app/current;RAILS_ENV=staging script/delayed_job restart"
    servers: ["staging.app.com"]
    [staging.app.com] executing command
 ** [out :: staging.app.com] Warning: no instances running. Starting...
 ** [out :: staging.app.com] delayed_job: process with pid 21950 started.
    command finished in 6758ms

它不会停止现有流程。奇怪的是,这次它将创建一个新的进程它的.pid文件。

这使得我运行了2个delayed_jobs进程,并且只有一个在.pid文件中。每增加2个上限,我会添加另一个delayed_job进程。之前的流程正在使用旧版本的应用程序,基本上是破解它。

配置/ deploy.rb:

namespace :passenger do
  desc "Restart Application"  
  task :restart do  
    run "touch #{current_path}/tmp/restart.txt"
    run "cd #{current_path};RAILS_ENV=#{deploy_env} script/delayed_job restart"
  end
end
after :deploy, "passenger:restart"
  • Ubuntu,nginx,乘客
  • 守护进程(1.1.4)
  • delayed_job(2.1.4)
  • rails(3.0.9)

本地

  • capistrano(2.9.0)
  • capistrano-ext(1.2.1)

更新

阅读,似乎可能与守护进程内的竞争条件有关。但是我有点困惑为什么它在使用capistrano时只显示(并且始终如一)。我会尝试将命令改为停止,然后再开始睡眠。

3 个答案:

答案 0 :(得分:7)

通过使用停止和启动而不是重新启动来解决。由于竞争条件可能由守护进程宝石造成。

我仍然想知道其他人是否有更好的解决方案。

答案 1 :(得分:0)

我遇到了这个问题,停止并开始没有为我工作,所以我想出了以下内容:

namespace :delayed_job do
desc 'Restart delayed_job worker'
  task :restart do
    on roles(:delayed_job) do
      within release_path do
        with rails_env: fetch(:rails_env) do
          execute :pkill , "-f", "'delayed_job'"
          execute :bundle, :exec, "bin/delayed_job", :start
        end
      end
    end
  end
end
...
after :restart,  "delayed_job:restart"

不是pkill的忠实粉丝,但这对我来说始终如一。希望这有帮助

答案 2 :(得分:0)

在每次部署过程中,Capistrano都会为当前目录混排一个符号链接,这正为我孤立了PID。我们使用capistrano3-delayed-job宝石,建议将其中一个修复程序应用到deploy.rb:

set :linked_dirs, %w(tmp/pids)

# or

set :delayed_job_pid_dir, '/tmp'

其中第一个为我们解决了这个问题。它将当前/ tmp / pids移到shared / tmp /并在当前树中进行符号链接,以使其在部署中持久存在。