I'm wondering what's the best way to gracefully restart delayed_job consumers after a new code push? I'm pushing code with capistrano and I know there are commands to restart, but if there are jobs currently running, the command either hangs (and my deploy takes forever) or it forcefully quits the currently running job and I lose data.
Ideally I'd like my deploy to happen like this:
- Existing delayed_job consumer is running with version 1 code
- I run
cap deploy
and version 2 code is pushed out to new servers - During the deploy, we touch a file to tell the delayed_job to restart when it's done processing the current job. This can be done a bunch of different ways, but I was thinking it would be similar to how passenger is gracefully restarted
- Existing delayed_job consumer continues to finish the current job with version 1 code
- Current job finishes, delayed_job consumer sees that it needs to restart itself before continuing to process jobs
- delayed_job consumer automatically restarts, now running version 2 code
- delayed_job consumer continues to process jobs, now running on version 2 code
I've tried to insert some code to restart before a job runs by checking the current revision of the code but every time I do that, it just dies and doesn't actually restart anything. Sample code below:
def before(job)
# check to make sure that the version of code here is the right version of code
live_git_hash = LIVE_REVISION
local_git_hash = LOCAL_REVISION
if live_git_hash != local_git_hash
# get environment to reload in
environment = Rails.env # production, development, staging
# restart the delayed job system
%x("export RAILS_ENV=#{environment} && ./script/delayed_job restart")
end
end
It detects it just fine but it dies on the shell call. Any ideas?
Thanks!