Skip to content

Instantly share code, notes, and snippets.

@bkutil
Forked from andruby/deploy.rb
Created December 4, 2011 22:22
Show Gist options
  • Select an option

  • Save bkutil/1431483 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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
Copy Markdown
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
Copy Markdown

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

@shadoath
Copy link
Copy Markdown

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

@chrishough
Copy link
Copy Markdown

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