sidekiq 5.2.3 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.circleci/config.yml +61 -0
- data/.gitignore +1 -1
- data/.standard.yml +20 -0
- data/6.0-Upgrade.md +70 -0
- data/COMM-LICENSE +11 -9
- data/Changes.md +61 -0
- data/Ent-2.0-Upgrade.md +37 -0
- data/Ent-Changes.md +27 -1
- data/Gemfile +19 -9
- data/Gemfile.lock +196 -0
- data/Pro-5.0-Upgrade.md +25 -0
- data/Pro-Changes.md +19 -2
- data/README.md +17 -31
- data/Rakefile +6 -4
- data/bin/sidekiqload +27 -23
- data/bin/sidekiqmon +9 -0
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/generators/sidekiq/worker_generator.rb +12 -14
- data/lib/sidekiq.rb +56 -43
- data/lib/sidekiq/api.rb +138 -151
- data/lib/sidekiq/cli.rb +141 -206
- data/lib/sidekiq/client.rb +45 -46
- data/lib/sidekiq/delay.rb +5 -6
- data/lib/sidekiq/exception_handler.rb +10 -12
- data/lib/sidekiq/extensions/action_mailer.rb +10 -20
- data/lib/sidekiq/extensions/active_record.rb +9 -7
- data/lib/sidekiq/extensions/class_methods.rb +9 -7
- data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
- data/lib/sidekiq/fetch.rb +5 -6
- data/lib/sidekiq/job_logger.rb +37 -7
- data/lib/sidekiq/job_retry.rb +55 -57
- data/lib/sidekiq/launcher.rb +59 -51
- data/lib/sidekiq/logger.rb +69 -0
- data/lib/sidekiq/manager.rb +7 -9
- data/lib/sidekiq/middleware/chain.rb +3 -2
- data/lib/sidekiq/middleware/i18n.rb +5 -7
- data/lib/sidekiq/monitor.rb +148 -0
- data/lib/sidekiq/paginator.rb +11 -12
- data/lib/sidekiq/processor.rb +68 -58
- data/lib/sidekiq/rails.rb +24 -29
- data/lib/sidekiq/redis_connection.rb +31 -37
- data/lib/sidekiq/scheduled.rb +17 -19
- data/lib/sidekiq/testing.rb +22 -23
- data/lib/sidekiq/testing/inline.rb +2 -1
- data/lib/sidekiq/util.rb +17 -14
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web.rb +41 -49
- data/lib/sidekiq/web/action.rb +14 -10
- data/lib/sidekiq/web/application.rb +61 -58
- data/lib/sidekiq/web/helpers.rb +72 -66
- data/lib/sidekiq/web/router.rb +17 -14
- data/lib/sidekiq/worker.rb +134 -102
- data/sidekiq.gemspec +16 -18
- data/web/assets/javascripts/dashboard.js +2 -21
- data/web/assets/stylesheets/bootstrap.css +1 -1
- data/web/locales/ja.yml +2 -1
- data/web/views/queues.erb +1 -1
- metadata +31 -26
- data/.travis.yml +0 -14
- data/bin/sidekiqctl +0 -237
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -23
    
        data/lib/sidekiq/cli.rb
    CHANGED
    
    | @@ -1,45 +1,29 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 2 3 | 
             
            $stdout.sync = true
         | 
| 3 4 |  | 
| 4 | 
            -
            require  | 
| 5 | 
            -
            require  | 
| 6 | 
            -
            require  | 
| 7 | 
            -
            require  | 
| 8 | 
            -
            require  | 
| 5 | 
            +
            require "yaml"
         | 
| 6 | 
            +
            require "singleton"
         | 
| 7 | 
            +
            require "optparse"
         | 
| 8 | 
            +
            require "erb"
         | 
| 9 | 
            +
            require "fileutils"
         | 
| 9 10 |  | 
| 10 | 
            -
            require  | 
| 11 | 
            -
            require  | 
| 11 | 
            +
            require "sidekiq"
         | 
| 12 | 
            +
            require "sidekiq/launcher"
         | 
| 13 | 
            +
            require "sidekiq/util"
         | 
| 12 14 |  | 
| 13 15 | 
             
            module Sidekiq
         | 
| 14 16 | 
             
              class CLI
         | 
| 15 17 | 
             
                include Util
         | 
| 16 18 | 
             
                include Singleton unless $TESTING
         | 
| 17 19 |  | 
| 18 | 
            -
                PROCTITLES = [
         | 
| 19 | 
            -
                  proc { 'sidekiq' },
         | 
| 20 | 
            -
                  proc { Sidekiq::VERSION },
         | 
| 21 | 
            -
                  proc { |me, data| data['tag'] },
         | 
| 22 | 
            -
                  proc { |me, data| "[#{Processor::WORKER_STATE.size} of #{data['concurrency']} busy]" },
         | 
| 23 | 
            -
                  proc { |me, data| "stopping" if me.stopping? },
         | 
| 24 | 
            -
                ]
         | 
| 25 | 
            -
             | 
| 26 | 
            -
                # Used for CLI testing
         | 
| 27 | 
            -
                attr_accessor :code
         | 
| 28 20 | 
             
                attr_accessor :launcher
         | 
| 29 21 | 
             
                attr_accessor :environment
         | 
| 30 22 |  | 
| 31 | 
            -
                def  | 
| 32 | 
            -
                  @code = nil
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def parse(args=ARGV)
         | 
| 36 | 
            -
                  @code = nil
         | 
| 37 | 
            -
             | 
| 23 | 
            +
                def parse(args = ARGV)
         | 
| 38 24 | 
             
                  setup_options(args)
         | 
| 39 25 | 
             
                  initialize_logger
         | 
| 40 26 | 
             
                  validate!
         | 
| 41 | 
            -
                  daemonize
         | 
| 42 | 
            -
                  write_pid
         | 
| 43 27 | 
             
                end
         | 
| 44 28 |  | 
| 45 29 | 
             
                def jruby?
         | 
| @@ -51,24 +35,18 @@ module Sidekiq | |
| 51 35 | 
             
                # test coverage of Sidekiq::CLI are welcomed.
         | 
| 52 36 | 
             
                def run
         | 
| 53 37 | 
             
                  boot_system
         | 
| 54 | 
            -
                   | 
| 55 | 
            -
             | 
| 56 | 
            -
                  self_read, self_write = IO.pipe
         | 
| 57 | 
            -
                  sigs = %w(INT TERM TTIN TSTP)
         | 
| 58 | 
            -
                  # USR1 and USR2 don't work on the JVM
         | 
| 59 | 
            -
                  if !jruby?
         | 
| 60 | 
            -
                    sigs << 'USR1'
         | 
| 61 | 
            -
                    sigs << 'USR2'
         | 
| 38 | 
            +
                  if environment == "development" && $stdout.tty? && Sidekiq.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
         | 
| 39 | 
            +
                    print_banner
         | 
| 62 40 | 
             
                  end
         | 
| 63 41 |  | 
| 42 | 
            +
                  self_read, self_write = IO.pipe
         | 
| 43 | 
            +
                  sigs = %w[INT TERM TTIN TSTP]
         | 
| 64 44 | 
             
                  sigs.each do |sig|
         | 
| 65 | 
            -
                     | 
| 66 | 
            -
                       | 
| 67 | 
            -
                        self_write.write("#{sig}\n")
         | 
| 68 | 
            -
                      end
         | 
| 69 | 
            -
                    rescue ArgumentError
         | 
| 70 | 
            -
                      puts "Signal #{sig} not supported"
         | 
| 45 | 
            +
                    trap sig do
         | 
| 46 | 
            +
                      self_write.write("#{sig}\n")
         | 
| 71 47 | 
             
                    end
         | 
| 48 | 
            +
                  rescue ArgumentError
         | 
| 49 | 
            +
                    puts "Signal #{sig} not supported"
         | 
| 72 50 | 
             
                  end
         | 
| 73 51 |  | 
| 74 52 | 
             
                  logger.info "Running in #{RUBY_DESCRIPTION}"
         | 
| @@ -77,8 +55,8 @@ module Sidekiq | |
| 77 55 |  | 
| 78 56 | 
             
                  # touch the connection pool so it is created before we
         | 
| 79 57 | 
             
                  # fire startup and start multithreading.
         | 
| 80 | 
            -
                  ver = Sidekiq.redis_info[ | 
| 81 | 
            -
                  raise "You are using Redis v#{ver}, Sidekiq requires Redis  | 
| 58 | 
            +
                  ver = Sidekiq.redis_info["redis_version"]
         | 
| 59 | 
            +
                  raise "You are using Redis v#{ver}, Sidekiq requires Redis v4.0.0 or greater" if ver < "4"
         | 
| 82 60 |  | 
| 83 61 | 
             
                  # Since the user can pass us a connection pool explicitly in the initializer, we
         | 
| 84 62 | 
             
                  # need to verify the size is large enough or else Sidekiq's performance is dramatically slowed.
         | 
| @@ -96,73 +74,86 @@ module Sidekiq | |
| 96 74 | 
             
                  # Starting here the process will now have multiple threads running.
         | 
| 97 75 | 
             
                  fire_event(:startup, reverse: false, reraise: true)
         | 
| 98 76 |  | 
| 99 | 
            -
                  logger.debug { "Client Middleware: #{Sidekiq.client_middleware.map(&:klass).join( | 
| 100 | 
            -
                  logger.debug { "Server Middleware: #{Sidekiq.server_middleware.map(&:klass).join( | 
| 77 | 
            +
                  logger.debug { "Client Middleware: #{Sidekiq.client_middleware.map(&:klass).join(", ")}" }
         | 
| 78 | 
            +
                  logger.debug { "Server Middleware: #{Sidekiq.server_middleware.map(&:klass).join(", ")}" }
         | 
| 101 79 |  | 
| 102 | 
            -
                   | 
| 103 | 
            -
             | 
| 80 | 
            +
                  launch(self_read)
         | 
| 81 | 
            +
                end
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                def launch(self_read)
         | 
| 84 | 
            +
                  if environment == "development" && $stdout.tty?
         | 
| 85 | 
            +
                    logger.info "Starting processing, hit Ctrl-C to stop"
         | 
| 104 86 | 
             
                  end
         | 
| 105 87 |  | 
| 106 | 
            -
                  require 'sidekiq/launcher'
         | 
| 107 88 | 
             
                  @launcher = Sidekiq::Launcher.new(options)
         | 
| 108 89 |  | 
| 109 90 | 
             
                  begin
         | 
| 110 91 | 
             
                    launcher.run
         | 
| 111 92 |  | 
| 112 | 
            -
                    while readable_io = IO.select([self_read])
         | 
| 93 | 
            +
                    while (readable_io = IO.select([self_read]))
         | 
| 113 94 | 
             
                      signal = readable_io.first[0].gets.strip
         | 
| 114 95 | 
             
                      handle_signal(signal)
         | 
| 115 96 | 
             
                    end
         | 
| 116 97 | 
             
                  rescue Interrupt
         | 
| 117 | 
            -
                    logger.info  | 
| 98 | 
            +
                    logger.info "Shutting down"
         | 
| 118 99 | 
             
                    launcher.stop
         | 
| 119 | 
            -
                    # Explicitly exit so busy Processor threads can't block
         | 
| 120 | 
            -
                    # process shutdown.
         | 
| 121 100 | 
             
                    logger.info "Bye!"
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                    # Explicitly exit so busy Processor threads won't block process shutdown.
         | 
| 103 | 
            +
                    #
         | 
| 104 | 
            +
                    # NB: slow at_exit handlers will prevent a timely exit if they take
         | 
| 105 | 
            +
                    # a while to run. If Sidekiq is getting here but the process isn't exiting,
         | 
| 106 | 
            +
                    # use the TTIN signal to determine where things are stuck.
         | 
| 122 107 | 
             
                    exit(0)
         | 
| 123 108 | 
             
                  end
         | 
| 124 109 | 
             
                end
         | 
| 125 110 |  | 
| 111 | 
            +
                def self.w
         | 
| 112 | 
            +
                  "\e[37m"
         | 
| 113 | 
            +
                end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                def self.r
         | 
| 116 | 
            +
                  "\e[31m"
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                def self.b
         | 
| 120 | 
            +
                  "\e[30m"
         | 
| 121 | 
            +
                end
         | 
| 122 | 
            +
             | 
| 123 | 
            +
                def self.reset
         | 
| 124 | 
            +
                  "\e[0m"
         | 
| 125 | 
            +
                end
         | 
| 126 | 
            +
             | 
| 126 127 | 
             
                def self.banner
         | 
| 127 | 
            -
            % | 
| 128 | 
            -
                     m,
         | 
| 129 | 
            -
                     `$b
         | 
| 130 | 
            -
                .ss,  $$:         .,d$
         | 
| 131 | 
            -
                `$$P,d$P'    .,md$P"'
         | 
| 132 | 
            -
                 ,$$$$$ | 
| 133 | 
            -
               .d | 
| 134 | 
            -
               $$^' `" | 
| 135 | 
            -
               $:     ,$$: | 
| 136 | 
            -
               `b     :$$ | 
| 137 | 
            -
                      $$: | 
| 138 | 
            -
                      $$         |____/|_ | 
| 139 | 
            -
                    .d$$ | 
| 140 | 
            -
            }
         | 
| 128 | 
            +
                  %{
         | 
| 129 | 
            +
                  #{w}         m,
         | 
| 130 | 
            +
                  #{w}         `$b
         | 
| 131 | 
            +
                  #{w}    .ss,  $$:         .,d$
         | 
| 132 | 
            +
                  #{w}    `$$P,d$P'    .,md$P"'
         | 
| 133 | 
            +
                  #{w}     ,$$$$$b#{b}/#{w}md$$$P^'
         | 
| 134 | 
            +
                  #{w}   .d$$$$$$#{b}/#{w}$$$P'
         | 
| 135 | 
            +
                  #{w}   $$^' `"#{b}/#{w}$$$'       #{r}____  _     _      _    _
         | 
| 136 | 
            +
                  #{w}   $:     ,$$:      #{r} / ___|(_) __| | ___| | _(_) __ _
         | 
| 137 | 
            +
                  #{w}   `b     :$$       #{r} \\___ \\| |/ _` |/ _ \\ |/ / |/ _` |
         | 
| 138 | 
            +
                  #{w}          $$:        #{r} ___) | | (_| |  __/   <| | (_| |
         | 
| 139 | 
            +
                  #{w}          $$         #{r}|____/|_|\\__,_|\\___|_|\\_\\_|\\__, |
         | 
| 140 | 
            +
                  #{w}        .d$$          #{r}                             |_|
         | 
| 141 | 
            +
                  #{reset}}
         | 
| 141 142 | 
             
                end
         | 
| 142 143 |  | 
| 143 144 | 
             
                SIGNAL_HANDLERS = {
         | 
| 144 145 | 
             
                  # Ctrl-C in terminal
         | 
| 145 | 
            -
                   | 
| 146 | 
            +
                  "INT" => ->(cli) { raise Interrupt },
         | 
| 146 147 | 
             
                  # TERM is the signal that Sidekiq must exit.
         | 
| 147 148 | 
             
                  # Heroku sends TERM and then waits 30 seconds for process to exit.
         | 
| 148 | 
            -
                   | 
| 149 | 
            -
                   | 
| 150 | 
            -
                    Sidekiq.logger.info "Received USR1, no longer accepting new work"
         | 
| 151 | 
            -
                    cli.launcher.quiet
         | 
| 152 | 
            -
                  },
         | 
| 153 | 
            -
                  'TSTP' => ->(cli) {
         | 
| 149 | 
            +
                  "TERM" => ->(cli) { raise Interrupt },
         | 
| 150 | 
            +
                  "TSTP" => ->(cli) {
         | 
| 154 151 | 
             
                    Sidekiq.logger.info "Received TSTP, no longer accepting new work"
         | 
| 155 152 | 
             
                    cli.launcher.quiet
         | 
| 156 153 | 
             
                  },
         | 
| 157 | 
            -
                   | 
| 158 | 
            -
                    if Sidekiq.options[:logfile]
         | 
| 159 | 
            -
                      Sidekiq.logger.info "Received USR2, reopening log file"
         | 
| 160 | 
            -
                      Sidekiq::Logging.reopen_logs
         | 
| 161 | 
            -
                    end
         | 
| 162 | 
            -
                  },
         | 
| 163 | 
            -
                  'TTIN' => ->(cli) {
         | 
| 154 | 
            +
                  "TTIN" => ->(cli) {
         | 
| 164 155 | 
             
                    Thread.list.each do |thread|
         | 
| 165 | 
            -
                      Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread | 
| 156 | 
            +
                      Sidekiq.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
         | 
| 166 157 | 
             
                      if thread.backtrace
         | 
| 167 158 | 
             
                        Sidekiq.logger.warn thread.backtrace.join("\n")
         | 
| 168 159 | 
             
                      else
         | 
| @@ -185,53 +176,20 @@ module Sidekiq | |
| 185 176 | 
             
                private
         | 
| 186 177 |  | 
| 187 178 | 
             
                def print_banner
         | 
| 188 | 
            -
                   | 
| 189 | 
            -
                   | 
| 190 | 
            -
             | 
| 191 | 
            -
                    puts Sidekiq::CLI.banner
         | 
| 192 | 
            -
                    puts "\e[0m"
         | 
| 193 | 
            -
                  end
         | 
| 194 | 
            -
                end
         | 
| 195 | 
            -
             | 
| 196 | 
            -
                def daemonize
         | 
| 197 | 
            -
                  return unless options[:daemon]
         | 
| 198 | 
            -
             | 
| 199 | 
            -
                  raise ArgumentError, "You really should set a logfile if you're going to daemonize" unless options[:logfile]
         | 
| 200 | 
            -
                  files_to_reopen = []
         | 
| 201 | 
            -
                  ObjectSpace.each_object(File) do |file|
         | 
| 202 | 
            -
                    files_to_reopen << file unless file.closed?
         | 
| 203 | 
            -
                  end
         | 
| 204 | 
            -
             | 
| 205 | 
            -
                  ::Process.daemon(true, true)
         | 
| 206 | 
            -
             | 
| 207 | 
            -
                  files_to_reopen.each do |file|
         | 
| 208 | 
            -
                    begin
         | 
| 209 | 
            -
                      file.reopen file.path, "a+"
         | 
| 210 | 
            -
                      file.sync = true
         | 
| 211 | 
            -
                    rescue ::Exception
         | 
| 212 | 
            -
                    end
         | 
| 213 | 
            -
                  end
         | 
| 214 | 
            -
             | 
| 215 | 
            -
                  [$stdout, $stderr].each do |io|
         | 
| 216 | 
            -
                    File.open(options[:logfile], 'ab') do |f|
         | 
| 217 | 
            -
                      io.reopen(f)
         | 
| 218 | 
            -
                    end
         | 
| 219 | 
            -
                    io.sync = true
         | 
| 220 | 
            -
                  end
         | 
| 221 | 
            -
                  $stdin.reopen('/dev/null')
         | 
| 222 | 
            -
             | 
| 223 | 
            -
                  initialize_logger
         | 
| 179 | 
            +
                  puts "\e[31m"
         | 
| 180 | 
            +
                  puts Sidekiq::CLI.banner
         | 
| 181 | 
            +
                  puts "\e[0m"
         | 
| 224 182 | 
             
                end
         | 
| 225 183 |  | 
| 226 184 | 
             
                def set_environment(cli_env)
         | 
| 227 | 
            -
                  @environment = cli_env || ENV[ | 
| 185 | 
            +
                  @environment = cli_env || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
         | 
| 228 186 | 
             
                end
         | 
| 229 187 |  | 
| 230 188 | 
             
                def symbolize_keys_deep!(hash)
         | 
| 231 189 | 
             
                  hash.keys.each do |k|
         | 
| 232 190 | 
             
                    symkey = k.respond_to?(:to_sym) ? k.to_sym : k
         | 
| 233 191 | 
             
                    hash[symkey] = hash.delete k
         | 
| 234 | 
            -
                    symbolize_keys_deep! hash[symkey] if hash[symkey]. | 
| 192 | 
            +
                    symbolize_keys_deep! hash[symkey] if hash[symkey].is_a? Hash
         | 
| 235 193 | 
             
                  end
         | 
| 236 194 | 
             
                end
         | 
| 237 195 |  | 
| @@ -239,15 +197,38 @@ module Sidekiq | |
| 239 197 | 
             
                alias_method :☠, :exit
         | 
| 240 198 |  | 
| 241 199 | 
             
                def setup_options(args)
         | 
| 200 | 
            +
                  # parse CLI options
         | 
| 242 201 | 
             
                  opts = parse_options(args)
         | 
| 202 | 
            +
             | 
| 243 203 | 
             
                  set_environment opts[:environment]
         | 
| 244 204 |  | 
| 245 | 
            -
                   | 
| 246 | 
            -
                   | 
| 205 | 
            +
                  # check config file presence
         | 
| 206 | 
            +
                  if opts[:config_file]
         | 
| 207 | 
            +
                    if opts[:config_file] && !File.exist?(opts[:config_file])
         | 
| 208 | 
            +
                      raise ArgumentError, "No such file #{opts[:config_file]}"
         | 
| 209 | 
            +
                    end
         | 
| 210 | 
            +
                  else
         | 
| 211 | 
            +
                    config_dir = if File.directory?(opts[:require].to_s)
         | 
| 212 | 
            +
                      File.join(opts[:require], "config")
         | 
| 213 | 
            +
                    else
         | 
| 214 | 
            +
                      File.join(options[:require], "config")
         | 
| 215 | 
            +
                    end
         | 
| 216 | 
            +
             | 
| 217 | 
            +
                    %w[sidekiq.yml sidekiq.yml.erb].each do |config_file|
         | 
| 218 | 
            +
                      path = File.join(config_dir, config_file)
         | 
| 219 | 
            +
                      opts[:config_file] ||= path if File.exist?(path)
         | 
| 220 | 
            +
                    end
         | 
| 221 | 
            +
                  end
         | 
| 222 | 
            +
             | 
| 223 | 
            +
                  # parse config file options
         | 
| 224 | 
            +
                  opts = parse_config(opts[:config_file]).merge(opts) if opts[:config_file]
         | 
| 247 225 |  | 
| 226 | 
            +
                  # set defaults
         | 
| 227 | 
            +
                  opts[:queues] = Array(opts[:queues]) << "default" if opts[:queues].nil? || opts[:queues].empty?
         | 
| 248 228 | 
             
                  opts[:strict] = true if opts[:strict].nil?
         | 
| 249 | 
            -
                  opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if  | 
| 229 | 
            +
                  opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if opts[:concurrency].nil? && ENV["RAILS_MAX_THREADS"]
         | 
| 250 230 |  | 
| 231 | 
            +
                  # merge with defaults
         | 
| 251 232 | 
             
                  options.merge!(opts)
         | 
| 252 233 | 
             
                end
         | 
| 253 234 |  | 
| @@ -256,41 +237,28 @@ module Sidekiq | |
| 256 237 | 
             
                end
         | 
| 257 238 |  | 
| 258 239 | 
             
                def boot_system
         | 
| 259 | 
            -
                  ENV[ | 
| 260 | 
            -
             | 
| 261 | 
            -
                  raise ArgumentError, "#{options[:require]} does not exist" unless File.exist?(options[:require])
         | 
| 240 | 
            +
                  ENV["RACK_ENV"] = ENV["RAILS_ENV"] = environment
         | 
| 262 241 |  | 
| 263 242 | 
             
                  if File.directory?(options[:require])
         | 
| 264 | 
            -
                    require  | 
| 265 | 
            -
                    if ::Rails::VERSION::MAJOR <  | 
| 243 | 
            +
                    require "rails"
         | 
| 244 | 
            +
                    if ::Rails::VERSION::MAJOR < 5
         | 
| 266 245 | 
             
                      raise "Sidekiq no longer supports this version of Rails"
         | 
| 267 | 
            -
                    elsif ::Rails::VERSION::MAJOR == 4
         | 
| 268 | 
            -
                      # Painful contortions, see 1791 for discussion
         | 
| 269 | 
            -
                      # No autoloading, we want to force eager load for everything.
         | 
| 270 | 
            -
                      require File.expand_path("#{options[:require]}/config/application.rb")
         | 
| 271 | 
            -
                      ::Rails::Application.initializer "sidekiq.eager_load" do
         | 
| 272 | 
            -
                        ::Rails.application.config.eager_load = true
         | 
| 273 | 
            -
                      end
         | 
| 274 | 
            -
                      require 'sidekiq/rails'
         | 
| 275 | 
            -
                      require File.expand_path("#{options[:require]}/config/environment.rb")
         | 
| 276 246 | 
             
                    else
         | 
| 277 | 
            -
                      require  | 
| 247 | 
            +
                      require "sidekiq/rails"
         | 
| 278 248 | 
             
                      require File.expand_path("#{options[:require]}/config/environment.rb")
         | 
| 279 249 | 
             
                    end
         | 
| 280 250 | 
             
                    options[:tag] ||= default_tag
         | 
| 281 251 | 
             
                  else
         | 
| 282 | 
            -
                     | 
| 283 | 
            -
                        "./#{options[:require]} or /path/to/#{options[:require]}"
         | 
| 284 | 
            -
             | 
| 285 | 
            -
                    require(options[:require]) || raise(ArgumentError, not_required_message)
         | 
| 252 | 
            +
                    require options[:require]
         | 
| 286 253 | 
             
                  end
         | 
| 287 254 | 
             
                end
         | 
| 288 255 |  | 
| 289 256 | 
             
                def default_tag
         | 
| 290 257 | 
             
                  dir = ::Rails.root
         | 
| 291 258 | 
             
                  name = File.basename(dir)
         | 
| 292 | 
            -
                   | 
| 293 | 
            -
             | 
| 259 | 
            +
                  prevdir = File.dirname(dir) # Capistrano release directory?
         | 
| 260 | 
            +
                  if name.to_i != 0 && prevdir
         | 
| 261 | 
            +
                    if File.basename(prevdir) == "releases"
         | 
| 294 262 | 
             
                      return File.basename(File.dirname(prevdir))
         | 
| 295 263 | 
             
                    end
         | 
| 296 264 | 
             
                  end
         | 
| @@ -298,12 +266,10 @@ module Sidekiq | |
| 298 266 | 
             
                end
         | 
| 299 267 |  | 
| 300 268 | 
             
                def validate!
         | 
| 301 | 
            -
                  options[:queues] << 'default' if options[:queues].empty?
         | 
| 302 | 
            -
             | 
| 303 269 | 
             
                  if !File.exist?(options[:require]) ||
         | 
| 304 | 
            -
             | 
| 270 | 
            +
                      (File.directory?(options[:require]) && !File.exist?("#{options[:require]}/config/application.rb"))
         | 
| 305 271 | 
             
                    logger.info "=================================================================="
         | 
| 306 | 
            -
                    logger.info "  Please point  | 
| 272 | 
            +
                    logger.info "  Please point Sidekiq to a Rails application or a Ruby file  "
         | 
| 307 273 | 
             
                    logger.info "  to load your worker classes with -r [DIR|FILE]."
         | 
| 308 274 | 
             
                    logger.info "=================================================================="
         | 
| 309 275 | 
             
                    logger.info @parser
         | 
| @@ -311,46 +277,40 @@ module Sidekiq | |
| 311 277 | 
             
                  end
         | 
| 312 278 |  | 
| 313 279 | 
             
                  [:concurrency, :timeout].each do |opt|
         | 
| 314 | 
            -
                    raise ArgumentError, "#{opt}: #{options[opt]} is not a valid value" if options. | 
| 280 | 
            +
                    raise ArgumentError, "#{opt}: #{options[opt]} is not a valid value" if options.key?(opt) && options[opt].to_i <= 0
         | 
| 315 281 | 
             
                  end
         | 
| 316 282 | 
             
                end
         | 
| 317 283 |  | 
| 318 284 | 
             
                def parse_options(argv)
         | 
| 319 285 | 
             
                  opts = {}
         | 
| 320 286 |  | 
| 321 | 
            -
                  @parser = OptionParser.new  | 
| 322 | 
            -
                    o.on  | 
| 287 | 
            +
                  @parser = OptionParser.new { |o|
         | 
| 288 | 
            +
                    o.on "-c", "--concurrency INT", "processor threads to use" do |arg|
         | 
| 323 289 | 
             
                      opts[:concurrency] = Integer(arg)
         | 
| 324 290 | 
             
                    end
         | 
| 325 291 |  | 
| 326 | 
            -
                    o.on  | 
| 327 | 
            -
                       | 
| 292 | 
            +
                    o.on "-d", "--daemon", "Daemonize process" do |arg|
         | 
| 293 | 
            +
                      puts "ERROR: Daemonization mode was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
         | 
| 328 294 | 
             
                    end
         | 
| 329 295 |  | 
| 330 | 
            -
                    o.on  | 
| 296 | 
            +
                    o.on "-e", "--environment ENV", "Application environment" do |arg|
         | 
| 331 297 | 
             
                      opts[:environment] = arg
         | 
| 332 298 | 
             
                    end
         | 
| 333 299 |  | 
| 334 | 
            -
                    o.on  | 
| 300 | 
            +
                    o.on "-g", "--tag TAG", "Process tag for procline" do |arg|
         | 
| 335 301 | 
             
                      opts[:tag] = arg
         | 
| 336 302 | 
             
                    end
         | 
| 337 303 |  | 
| 338 | 
            -
                    # this index remains here for backwards compatibility but none of the Sidekiq
         | 
| 339 | 
            -
                    # family use this value anymore.  it was used by Pro's original reliable_fetch.
         | 
| 340 | 
            -
                    o.on '-i', '--index INT', "unique process index on this machine" do |arg|
         | 
| 341 | 
            -
                      opts[:index] = Integer(arg.match(/\d+/)[0])
         | 
| 342 | 
            -
                    end
         | 
| 343 | 
            -
             | 
| 344 304 | 
             
                    o.on "-q", "--queue QUEUE[,WEIGHT]", "Queues to process with optional weights" do |arg|
         | 
| 345 305 | 
             
                      queue, weight = arg.split(",")
         | 
| 346 306 | 
             
                      parse_queue opts, queue, weight
         | 
| 347 307 | 
             
                    end
         | 
| 348 308 |  | 
| 349 | 
            -
                    o.on  | 
| 309 | 
            +
                    o.on "-r", "--require [PATH|DIR]", "Location of Rails application with workers or file to require" do |arg|
         | 
| 350 310 | 
             
                      opts[:require] = arg
         | 
| 351 311 | 
             
                    end
         | 
| 352 312 |  | 
| 353 | 
            -
                    o.on  | 
| 313 | 
            +
                    o.on "-t", "--timeout NUM", "Shutdown timeout" do |arg|
         | 
| 354 314 | 
             
                      opts[:timeout] = Integer(arg)
         | 
| 355 315 | 
             
                    end
         | 
| 356 316 |  | 
| @@ -358,76 +318,51 @@ module Sidekiq | |
| 358 318 | 
             
                      opts[:verbose] = arg
         | 
| 359 319 | 
             
                    end
         | 
| 360 320 |  | 
| 361 | 
            -
                    o.on  | 
| 321 | 
            +
                    o.on "-C", "--config PATH", "path to YAML config file" do |arg|
         | 
| 362 322 | 
             
                      opts[:config_file] = arg
         | 
| 363 323 | 
             
                    end
         | 
| 364 324 |  | 
| 365 | 
            -
                    o.on  | 
| 366 | 
            -
                       | 
| 325 | 
            +
                    o.on "-L", "--logfile PATH", "path to writable logfile" do |arg|
         | 
| 326 | 
            +
                      puts "ERROR: Logfile redirection was removed in Sidekiq 6.0, Sidekiq will only log to STDOUT"
         | 
| 367 327 | 
             
                    end
         | 
| 368 328 |  | 
| 369 | 
            -
                    o.on  | 
| 370 | 
            -
                       | 
| 329 | 
            +
                    o.on "-P", "--pidfile PATH", "path to pidfile" do |arg|
         | 
| 330 | 
            +
                      puts "ERROR: PID file creation was removed in Sidekiq 6.0, please use a proper process supervisor to start and manage your services"
         | 
| 371 331 | 
             
                    end
         | 
| 372 332 |  | 
| 373 | 
            -
                    o.on  | 
| 333 | 
            +
                    o.on "-V", "--version", "Print version and exit" do |arg|
         | 
| 374 334 | 
             
                      puts "Sidekiq #{Sidekiq::VERSION}"
         | 
| 375 335 | 
             
                      die(0)
         | 
| 376 336 | 
             
                    end
         | 
| 377 | 
            -
                   | 
| 337 | 
            +
                  }
         | 
| 378 338 |  | 
| 379 339 | 
             
                  @parser.banner = "sidekiq [options]"
         | 
| 380 340 | 
             
                  @parser.on_tail "-h", "--help", "Show help" do
         | 
| 381 341 | 
             
                    logger.info @parser
         | 
| 382 342 | 
             
                    die 1
         | 
| 383 343 | 
             
                  end
         | 
| 384 | 
            -
                  @parser.parse!(argv)
         | 
| 385 344 |  | 
| 386 | 
            -
                   | 
| 387 | 
            -
                    opts[:config_file] ||= filename if File.exist?(filename)
         | 
| 388 | 
            -
                  end
         | 
| 345 | 
            +
                  @parser.parse!(argv)
         | 
| 389 346 |  | 
| 390 347 | 
             
                  opts
         | 
| 391 348 | 
             
                end
         | 
| 392 349 |  | 
| 393 350 | 
             
                def initialize_logger
         | 
| 394 | 
            -
                  Sidekiq::Logging.initialize_logger(options[:logfile]) if options[:logfile]
         | 
| 395 | 
            -
             | 
| 396 351 | 
             
                  Sidekiq.logger.level = ::Logger::DEBUG if options[:verbose]
         | 
| 397 352 | 
             
                end
         | 
| 398 353 |  | 
| 399 | 
            -
                def  | 
| 400 | 
            -
                   | 
| 401 | 
            -
                    pidfile = File.expand_path(path)
         | 
| 402 | 
            -
                    File.open(pidfile, 'w') do |f|
         | 
| 403 | 
            -
                      f.puts ::Process.pid
         | 
| 404 | 
            -
                    end
         | 
| 405 | 
            -
                  end
         | 
| 406 | 
            -
                end
         | 
| 354 | 
            +
                def parse_config(path)
         | 
| 355 | 
            +
                  opts = YAML.load(ERB.new(File.read(path)).result) || {}
         | 
| 407 356 |  | 
| 408 | 
            -
             | 
| 409 | 
            -
             | 
| 410 | 
            -
                  if File.exist?(cfile)
         | 
| 411 | 
            -
                    opts = YAML.load(ERB.new(IO.read(cfile)).result) || opts
         | 
| 412 | 
            -
             | 
| 413 | 
            -
                    if opts.respond_to? :deep_symbolize_keys!
         | 
| 414 | 
            -
                      opts.deep_symbolize_keys!
         | 
| 415 | 
            -
                    else
         | 
| 416 | 
            -
                      symbolize_keys_deep!(opts)
         | 
| 417 | 
            -
                    end
         | 
| 418 | 
            -
             | 
| 419 | 
            -
                    opts = opts.merge(opts.delete(environment.to_sym) || {})
         | 
| 420 | 
            -
                    parse_queues(opts, opts.delete(:queues) || [])
         | 
| 357 | 
            +
                  if opts.respond_to? :deep_symbolize_keys!
         | 
| 358 | 
            +
                    opts.deep_symbolize_keys!
         | 
| 421 359 | 
             
                  else
         | 
| 422 | 
            -
                     | 
| 423 | 
            -
                    # can be deployed by cap with just the defaults.
         | 
| 424 | 
            -
                  end
         | 
| 425 | 
            -
                  ns = opts.delete(:namespace)
         | 
| 426 | 
            -
                  if ns
         | 
| 427 | 
            -
                    # logger hasn't been initialized yet, puts is all we have.
         | 
| 428 | 
            -
                    puts("namespace should be set in your ruby initializer, is ignored in config file")
         | 
| 429 | 
            -
                    puts("config.redis = { :url => ..., :namespace => '#{ns}' }")
         | 
| 360 | 
            +
                    symbolize_keys_deep!(opts)
         | 
| 430 361 | 
             
                  end
         | 
| 362 | 
            +
             | 
| 363 | 
            +
                  opts = opts.merge(opts.delete(environment.to_sym) || {})
         | 
| 364 | 
            +
                  parse_queues(opts, opts.delete(:queues) || [])
         | 
| 365 | 
            +
             | 
| 431 366 | 
             
                  opts
         | 
| 432 367 | 
             
                end
         | 
| 433 368 |  | 
| @@ -435,10 +370,10 @@ module Sidekiq | |
| 435 370 | 
             
                  queues_and_weights.each { |queue_and_weight| parse_queue(opts, *queue_and_weight) }
         | 
| 436 371 | 
             
                end
         | 
| 437 372 |  | 
| 438 | 
            -
                def parse_queue(opts,  | 
| 373 | 
            +
                def parse_queue(opts, queue, weight = nil)
         | 
| 439 374 | 
             
                  opts[:queues] ||= []
         | 
| 440 | 
            -
                  raise ArgumentError, "queues: #{ | 
| 441 | 
            -
                  [weight.to_i, 1].max.times { opts[:queues] <<  | 
| 375 | 
            +
                  raise ArgumentError, "queues: #{queue} cannot be defined twice" if opts[:queues].include?(queue)
         | 
| 376 | 
            +
                  [weight.to_i, 1].max.times { opts[:queues] << queue }
         | 
| 442 377 | 
             
                  opts[:strict] = false if weight.to_i > 0
         | 
| 443 378 | 
             
                end
         | 
| 444 379 | 
             
              end
         |