Skip to content

Instantly share code, notes, and snippets.

@bkutil
Forked from andruby/deploy.rb
Created December 4, 2011 22:22
Show Gist options
  • Save bkutil/1431483 to your computer and use it in GitHub Desktop.
Save bkutil/1431483 to your computer and use it in GitHub Desktop.
Start and Stop tasks for resque workers and resque scheduler with capistrano deploy hook (without God)
after "deploy:symlink", "deploy:restart_workers"
after "deploy:restart_workers", "deploy:restart_scheduler"
##
# Rake helper task.
# http://pastie.org/255489
# http://geminstallthat.wordpress.com/2008/01/27/rake-tasks-through-capistrano/
# http://ananelson.com/said/on/2007/12/30/remote-rake-tasks-with-capistrano/
def run_remote_rake(rake_cmd)
rake_args = ENV['RAKE_ARGS'].to_s.split(',')
cmd = "cd #{fetch(:latest_release)} && #{fetch(:rake, "rake")} RAILS_ENV=#{fetch(:rails_env, "production")} #{rake_cmd}"
cmd += "['#{rake_args.join("','")}']" unless rake_args.empty?
run cmd
set :rakefile, nil if exists?(:rakefile)
end
namespace :deploy do
desc "Restart Resque Workers"
task :restart_workers, :roles => :db do
run_remote_rake "resque:restart_workers"
end
desc "Restart Resque scheduler"
task :restart_scheduler, :roles => :db do
run_remote_rake "resque:restart_scheduler"
end
end
# Start a worker with proper env vars and output redirection
def run_worker(queue, count = 1)
puts "Starting #{count} worker(s) with QUEUE: #{queue}"
ops = {:pgroup => true, :err => [(Rails.root + "log/workers_error.log").to_s, "a"],
:out => [(Rails.root + "log/workers.log").to_s, "a"]}
env_vars = {"QUEUE" => queue.to_s}
count.times {
## Using Kernel.spawn and Process.detach because regular system() call would
## cause the processes to quit when capistrano finishes
pid = spawn(env_vars, "rake resque:work", ops)
Process.detach(pid)
}
end
# Start a scheduler, requires resque_scheduler >= 2.0.0.f
def run_scheduler
puts "Starting resque scheduler"
env_vars = {
"BACKGROUND" => "1",
"PIDFILE" => (Rails.root + "tmp/pids/resque_scheduler.pid").to_s,
"VERBOSE" => "1"
}
ops = {:pgroup => true, :err => [(Rails.root + "log/scheduler_error.log").to_s, "a"],
:out => [(Rails.root + "log/scheduler.log").to_s, "a"]}
pid = spawn(env_vars, "rake resque:scheduler", ops)
Process.detach(pid)
end
namespace :resque do
task :setup => :environment
desc "Restart running workers"
task :restart_workers => :environment do
Rake::Task['resque:stop_workers'].invoke
Rake::Task['resque:start_workers'].invoke
end
desc "Quit running workers"
task :stop_workers => :environment do
pids = Array.new
Resque.workers.each do |worker|
pids.concat(worker.worker_pids)
end
if pids.empty?
puts "No workers to kill"
else
syscmd = "kill -s QUIT #{pids.join(' ')}"
puts "Running syscmd: #{syscmd}"
system(syscmd)
end
end
desc "Start workers"
task :start_workers => :environment do
run_worker("*", 2)
run_worker("high", 1)
end
desc "Restart scheduler"
task :restart_scheduler => :environment do
Rake::Task['resque:stop_scheduler'].invoke
Rake::Task['resque:start_scheduler'].invoke
end
desc "Quit scheduler"
task :stop_scheduler => :environment do
pidfile = Rails.root + "tmp/pids/resque_scheduler.pid"
if !File.exists?(pidfile)
puts "Scheduler not running"
else
pid = File.read(pidfile).to_i
syscmd = "kill -s QUIT #{pid}"
puts "Running syscmd: #{syscmd}"
system(syscmd)
FileUtils.rm_f(pidfile)
end
end
desc "Start scheduler"
task :start_scheduler => :environment do
run_scheduler
end
desc "Reload schedule"
task :reload_schedule => :environment do
pidfile = Rails.root + "tmp/pids/resque_scheduler.pid"
if !File.exists?(pidfile)
puts "Scheduler not running"
else
pid = File.read(pidfile).to_i
syscmd = "kill -s USR2 #{pid}"
puts "Running syscmd: #{syscmd}"
system(syscmd)
end
end
end
@plentz
Copy link

plentz commented May 2, 2012

hey @bkutil, you're using this in production? have you optimized it in any way? I'm borrowing this code to my app :)

@bkutil
Copy link
Author

bkutil commented May 2, 2012

hi @plentz, I've been using this gist as is, without any modifications and just for private projects, not anything 'production ready' - it works for me, though :) Feel free to fork the gist and improve it in any way :)

@andreacfm
Copy link

Thanks for sharing.
The only issue is that I cannot get the logging working properly.
Did you update the script recently?

@shadoath
Copy link

Like to point out that this can be accomplished with a gem now. Checkout: https://github.com/sshingler/capistrano-resque

@chrishough
Copy link

Has anyone tried to modify this for heroku setups?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment