lib/capistrano/tasks/sidekiq.rake in capistrano-sidekiq-1.0.3 vs lib/capistrano/tasks/sidekiq.rake in capistrano-sidekiq-2.0.0.beta1

- old
+ new

@@ -1,286 +1,20 @@ -namespace :load do - task :defaults do - set :sidekiq_default_hooks, true - - set :sidekiq_pid, -> { File.join(shared_path, 'tmp', 'pids', 'sidekiq.pid') } - set :sidekiq_env, -> { fetch(:rack_env, fetch(:rails_env, fetch(:stage))) } - set :sidekiq_log, -> { File.join(shared_path, 'log', 'sidekiq.log') } - set :sidekiq_timeout, 10 - set :sidekiq_roles, fetch(:sidekiq_role, :app) - set :sidekiq_processes, 1 - set :sidekiq_options_per_process, nil - set :sidekiq_user, nil - # Rbenv, Chruby, and RVM integration - set :rbenv_map_bins, fetch(:rbenv_map_bins).to_a.concat(%w[sidekiq sidekiqctl]) - set :rvm_map_bins, fetch(:rvm_map_bins).to_a.concat(%w[sidekiq sidekiqctl]) - set :chruby_map_bins, fetch(:chruby_map_bins).to_a.concat(%w[sidekiq sidekiqctl]) - # Bundler integration - set :bundle_bins, fetch(:bundle_bins).to_a.concat(%w[sidekiq sidekiqctl]) - # Init system integration - set :init_system, -> { nil } - # systemd integration - set :service_unit_name, "sidekiq-#{fetch(:stage)}.service" - set :upstart_service_name, "sidekiq" - end -end - namespace :deploy do before :starting, :check_sidekiq_hooks do invoke 'sidekiq:add_default_hooks' if fetch(:sidekiq_default_hooks) end end namespace :sidekiq do task :add_default_hooks do - after 'deploy:starting', 'sidekiq:quiet' - after 'deploy:updated', 'sidekiq:stop' + after 'deploy:starting', 'sidekiq:quiet' + after 'deploy:updated', 'sidekiq:stop' after 'deploy:published', 'sidekiq:start' after 'deploy:failed', 'sidekiq:restart' end - desc 'Quiet sidekiq (stop fetching new tasks from Redis)' - task :quiet do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - case fetch(:init_system) - when :systemd - execute :systemctl, "--user", "reload", fetch(:service_unit_name), raise_on_non_zero_exit: false - when :upstart - sudo :service, fetch(:upstart_service_name), :reload - else - if test("[ -d #{release_path} ]") - each_process_with_index(reverse: true) do |pid_file, _idx| - if pid_file_exists?(pid_file) && process_exists?(pid_file) - quiet_sidekiq(pid_file) - end - end - end - end - end - end - end - - desc 'Stop sidekiq (graceful shutdown within timeout, put unfinished tasks back to Redis)' - task :stop do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - case fetch(:init_system) - when :systemd - execute :systemctl, "--user", "stop", fetch(:service_unit_name) - when :upstart - sudo :service, fetch(:upstart_service_name), :stop - else - if test("[ -d #{release_path} ]") - each_process_with_index(reverse: true) do |pid_file, _idx| - if pid_file_exists?(pid_file) && process_exists?(pid_file) - stop_sidekiq(pid_file) - end - end - end - end - end - end - end - - desc 'Start sidekiq' - task :start do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - case fetch(:init_system) - when :systemd - execute :systemctl, '--user', 'start', fetch(:service_unit_name) - when :upstart - sudo :service, fetch(:upstart_service_name), :start - else - each_process_with_index do |pid_file, idx| - unless pid_file_exists?(pid_file) && process_exists?(pid_file) - start_sidekiq(pid_file, idx) - end - end - end - end - end - end - desc 'Restart sidekiq' task :restart do invoke! 'sidekiq:stop' invoke! 'sidekiq:start' - end - - desc 'Rolling-restart sidekiq' - task :rolling_restart do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - each_process_with_index(reverse: true) do |pid_file, idx| - if pid_file_exists?(pid_file) && process_exists?(pid_file) - stop_sidekiq(pid_file) - end - start_sidekiq(pid_file, idx) - end - end - end - end - - desc 'Delete any pid file not in use' - task :cleanup do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - each_process_with_index do |pid_file, _idx| - unless process_exists?(pid_file) - next unless pid_file_exists?(pid_file) - execute "rm #{pid_file}" - end - end - end - end - end - - # TODO: Don't start if all processes are off, raise warning. - desc 'Respawn missing sidekiq processes' - task :respawn do - invoke 'sidekiq:cleanup' - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - each_process_with_index do |pid_file, idx| - start_sidekiq(pid_file, idx) unless pid_file_exists?(pid_file) - end - end - end - end - - task :install do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - case fetch(:init_system) - when :systemd - create_systemd_template - execute :systemctl, "--user", "enable", fetch(:service_unit_name) - end - end - end - end - - task :uninstall do - on roles fetch(:sidekiq_roles) do |role| - switch_user(role) do - case fetch(:init_system) - when :systemd - execute :systemctl, "--user", "disable", fetch(:service_unit_name) - execute :rm, File.join(fetch(:service_unit_path, fetch_systemd_unit_path),fetch(:service_unit_name)) - end - end - end - end - - def each_process_with_index(reverse: false) - pid_file_list = pid_files - pid_file_list.reverse! if reverse - pid_file_list.each_with_index do |pid_file, idx| - within release_path do - yield(pid_file, idx) - end - end - end - - def fetch_systemd_unit_path - home_dir = capture :pwd - File.join(home_dir, ".config", "systemd", "user") - end - - def create_systemd_template - search_paths = [ - File.expand_path( - File.join(*%w[.. .. .. generators capistrano sidekiq systemd templates sidekiq.service.capistrano.erb]), - __FILE__ - ), - ] - template_path = search_paths.detect {|path| File.file?(path)} - template = File.read(template_path) - systemd_path = fetch(:service_unit_path, fetch_systemd_unit_path) - execute :mkdir, "-p", systemd_path - upload!( - StringIO.new(ERB.new(template).result(binding)), - "#{systemd_path}/#{fetch :service_unit_name}" - ) - execute :systemctl, "--user", "daemon-reload" - end - - def pid_files - sidekiq_roles = Array(fetch(:sidekiq_roles)).dup - sidekiq_roles.select! { |role| host.roles.include?(role) } - sidekiq_roles.flat_map do |role| - processes = fetch(:"#{ role }_processes") || fetch(:sidekiq_processes) - Array.new(processes) { |idx| fetch(:sidekiq_pid).gsub(/\.pid$/, "-#{idx}.pid") } - end - end - - def pid_file_exists?(pid_file) - test(*("[ -f #{pid_file} ]").split(' ')) - end - - def process_exists?(pid_file) - test(*("kill -0 $( cat #{pid_file} )").split(' ')) - end - - def quiet_sidekiq(pid_file) - begin - execute :sidekiqctl, 'quiet', pid_file.to_s - rescue SSHKit::Command::Failed - # If gems are not installed (first deploy) and sidekiq_default_hooks is active - warn 'sidekiqctl not found (ignore if this is the first deploy)' - end - end - - def stop_sidekiq(pid_file) - execute :sidekiqctl, 'stop', pid_file.to_s, fetch(:sidekiq_timeout) - end - - def start_sidekiq(pid_file, idx = 0) - args = [] - args.push "--index #{idx}" - args.push "--pidfile #{pid_file}" - args.push "--environment #{fetch(:sidekiq_env)}" - args.push "--logfile #{fetch(:sidekiq_log)}" if fetch(:sidekiq_log) - args.push "--require #{fetch(:sidekiq_require)}" if fetch(:sidekiq_require) - args.push "--tag #{fetch(:sidekiq_tag)}" if fetch(:sidekiq_tag) - Array(fetch(:sidekiq_queue)).each do |queue| - args.push "--queue #{queue}" - end - args.push "--config #{fetch(:sidekiq_config)}" if fetch(:sidekiq_config) - args.push "--concurrency #{fetch(:sidekiq_concurrency)}" if fetch(:sidekiq_concurrency) - if (process_options = fetch(:sidekiq_options_per_process)) - args.push process_options[idx] - end - # use sidekiq_options for special options - args.push fetch(:sidekiq_options) if fetch(:sidekiq_options) - - if defined?(JRUBY_VERSION) - args.push '>/dev/null 2>&1 &' - warn 'Since JRuby doesn\'t support Process.daemon, Sidekiq will not be running as a daemon.' - else - args.push '--daemon' - end - - execute :sidekiq, args.compact.join(' ') - end - - def switch_user(role) - su_user = sidekiq_user(role) - if su_user == role.user - yield - else - as su_user do - yield - end - end - end - - def sidekiq_user(role) - properties = role.properties - properties.fetch(:sidekiq_user) || # local property for sidekiq only - fetch(:sidekiq_user) || - properties.fetch(:run_as) || # global property across multiple capistrano gems - role.user end end