Skip to content

Instantly share code, notes, and snippets.

@aishek
Last active December 27, 2015 08:58
Show Gist options
  • Save aishek/7299976 to your computer and use it in GitHub Desktop.
Save aishek/7299976 to your computer and use it in GitHub Desktop.
Sidekiq Capistrano extension to use different sidekiq_processes on different hosts. Disadvantage of using this extension is sequental only commands execution (no parallel execution support).
require 'sidekiq/capistrano'
load 'config/deploy/extensions/sidekiq' # required to be after require 'sidekiq/capistrano'
set :sidekiq_role, :sidekiq
role :sidekiq, 'server1.com', 'server2.com'
# you may use default syntax – same number of processes at all hosts
# set :sidekiq_processes, 1
# or use hash notation to specify host-dependent number of processes
set :sidekiq_processes, { 'server1.com' => 1, 'server2.com' => 2 }
# place this file into config/deploy/extensions/sidekiq.rb in Rails root folder
namespace :sidekiq do
def find_hosts_for_task(task, &block)
find_servers_for_task(current_task).map(&:host)
end
def for_each_process(current_host, &block)
sidekiq_processes = fetch(:sidekiq_processes)
begin
sidekiq_processes_for_current_server = sidekiq_processes[current_host]
rescue TypeError
sidekiq_processes_for_current_server = sidekiq_processes
end
sidekiq_processes_for_current_server.times do |idx|
yield((idx == 0 ? "#{fetch(:sidekiq_pid)}" : "#{fetch(:sidekiq_pid)}-#{idx}"), idx)
end
end
desc "Quiet sidekiq (stop accepting new work)"
task :quiet, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
sidekiqctl_cmd = fetch(:sidekiqctl_cmd)
find_hosts_for_task(current_task).each do |current_host|
for_each_process(current_host) do |pid_file, idx|
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{sidekiqctl_cmd} quiet #{pid_file} ; else echo 'Sidekiq is not running'; fi", :hosts => current_host
end
end
end
desc "Start sidekiq"
task :start, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
rails_env = fetch(:rails_env, "production")
sidekiq_cmd = fetch(:sidekiq_cmd)
find_hosts_for_task(current_task).each do |current_host|
for_each_process(current_host) do |pid_file, idx|
run "cd #{current_path} ; nohup #{sidekiq_cmd} -e #{rails_env} -C #{current_path}/config/sidekiq.yml -i #{idx} -P #{pid_file} >> #{current_path}/log/sidekiq.log 2>&1 &", :pty => false, :hosts => current_host
end
end
end
desc "Stop sidekiq"
task :stop, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
sidekiqctl_cmd = fetch(:sidekiqctl_cmd)
sidekiq_timeout = fetch(:sidekiq_timeout)
find_hosts_for_task(current_task).each do |current_host|
for_each_process(current_host) do |pid_file, idx|
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{sidekiqctl_cmd} stop #{pid_file} #{sidekiq_timeout} ; else echo 'Sidekiq is not running'; fi", :hosts => current_host
end
end
end
end
@mperham
Copy link

mperham commented Nov 4, 2013

Or this should work:

PROCS = { 'server1.com' => 1, 'server2.com' => 2 }
set :sidekiq_processes, -> { PROCS[current_host] }

@aishek
Copy link
Author

aishek commented Nov 4, 2013

@mperham not working with capistrano 2.15.5, unfortunately

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