sidekiq 4.1.1 → 4.2.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 +4 -4
 - data/.github/issue_template.md +4 -0
 - data/.travis.yml +3 -6
 - data/4.0-Upgrade.md +3 -0
 - data/COMM-LICENSE +1 -1
 - data/Changes.md +69 -0
 - data/Ent-Changes.md +40 -0
 - data/Gemfile +6 -5
 - data/Pro-3.0-Upgrade.md +5 -7
 - data/Pro-Changes.md +66 -0
 - data/README.md +2 -1
 - data/bin/sidekiqload +2 -2
 - data/lib/sidekiq.rb +5 -1
 - data/lib/sidekiq/api.rb +3 -1
 - data/lib/sidekiq/cli.rb +15 -2
 - data/lib/sidekiq/client.rb +11 -3
 - data/lib/sidekiq/core_ext.rb +1 -0
 - data/lib/sidekiq/exception_handler.rb +2 -1
 - data/lib/sidekiq/extensions/action_mailer.rb +1 -0
 - data/lib/sidekiq/extensions/active_record.rb +1 -0
 - data/lib/sidekiq/extensions/class_methods.rb +1 -0
 - data/lib/sidekiq/extensions/generic_proxy.rb +1 -0
 - data/lib/sidekiq/fetch.rb +1 -0
 - data/lib/sidekiq/launcher.rb +9 -3
 - data/lib/sidekiq/logging.rb +2 -1
 - data/lib/sidekiq/manager.rb +2 -0
 - data/lib/sidekiq/middleware/chain.rb +1 -0
 - data/lib/sidekiq/middleware/i18n.rb +1 -0
 - data/lib/sidekiq/middleware/server/retry_jobs.rb +7 -7
 - data/lib/sidekiq/paginator.rb +1 -0
 - data/lib/sidekiq/processor.rb +29 -25
 - data/lib/sidekiq/rails.rb +18 -0
 - data/lib/sidekiq/redis_connection.rb +6 -3
 - data/lib/sidekiq/scheduled.rb +2 -0
 - data/lib/sidekiq/testing.rb +1 -0
 - data/lib/sidekiq/testing/inline.rb +1 -0
 - data/lib/sidekiq/util.rb +1 -0
 - data/lib/sidekiq/version.rb +2 -1
 - data/lib/sidekiq/web.rb +80 -202
 - data/lib/sidekiq/web/action.rb +99 -0
 - data/lib/sidekiq/web/application.rb +335 -0
 - data/lib/sidekiq/{web_helpers.rb → web/helpers.rb} +31 -11
 - data/lib/sidekiq/web/router.rb +96 -0
 - data/lib/sidekiq/worker.rb +1 -0
 - data/sidekiq.gemspec +2 -2
 - data/test/fake_env.rb +1 -0
 - data/test/helper.rb +1 -0
 - data/test/test_actors.rb +1 -0
 - data/test/test_api.rb +1 -0
 - data/test/test_cli.rb +15 -2
 - data/test/test_client.rb +34 -0
 - data/test/test_exception_handler.rb +2 -1
 - data/test/test_extensions.rb +1 -0
 - data/test/test_fetch.rb +1 -0
 - data/test/test_launcher.rb +17 -2
 - data/test/test_logging.rb +1 -0
 - data/test/test_manager.rb +1 -0
 - data/test/test_middleware.rb +1 -0
 - data/test/test_processor.rb +1 -0
 - data/test/test_rails.rb +1 -0
 - data/test/test_redis_connection.rb +7 -1
 - data/test/test_retry.rb +1 -0
 - data/test/test_scheduled.rb +1 -0
 - data/test/test_scheduling.rb +1 -0
 - data/test/test_sidekiq.rb +1 -0
 - data/test/test_testing.rb +1 -0
 - data/test/test_testing_fake.rb +1 -0
 - data/test/test_testing_inline.rb +2 -1
 - data/test/test_util.rb +1 -0
 - data/test/test_web.rb +53 -5
 - data/test/test_web_helpers.rb +1 -0
 - data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
 - data/web/assets/javascripts/application.js +5 -0
 - data/web/assets/javascripts/locales/{jquery.timeago.no.js → jquery.timeago.nb.js} +1 -1
 - data/web/assets/stylesheets/application.css +26 -1
 - data/web/assets/stylesheets/bootstrap.css +4 -8
 - data/web/locales/de.yml +1 -1
 - data/web/locales/en.yml +1 -0
 - data/web/locales/ru.yml +3 -0
 - data/web/views/_footer.erb +1 -1
 - data/web/views/_nav.erb +1 -1
 - data/web/views/busy.erb +4 -4
 - data/web/views/dashboard.erb +2 -2
 - data/web/views/dead.erb +1 -1
 - data/web/views/layout.erb +3 -3
 - data/web/views/morgue.erb +2 -2
 - data/web/views/queue.erb +3 -3
 - data/web/views/queues.erb +1 -1
 - data/web/views/retries.erb +2 -2
 - data/web/views/retry.erb +1 -1
 - data/web/views/scheduled.erb +2 -2
 - data/web/views/scheduled_job_info.erb +1 -1
 - metadata +17 -29
 - data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
 - data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
 - data/web/assets/images/status/active.png +0 -0
 - data/web/assets/images/status/idle.png +0 -0
 - data/web/views/_poll_js.erb +0 -5
 
    
        data/lib/sidekiq/core_ext.rb
    CHANGED
    
    
| 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'sidekiq'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Sidekiq
         
     | 
| 
         @@ -5,7 +6,7 @@ module Sidekiq 
     | 
|
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
                class Logger
         
     | 
| 
       7 
8 
     | 
    
         
             
                  def call(ex, ctxHash)
         
     | 
| 
       8 
     | 
    
         
            -
                    Sidekiq.logger.warn(ctxHash) if !ctxHash.empty?
         
     | 
| 
      
 9 
     | 
    
         
            +
                    Sidekiq.logger.warn(Sidekiq.dump_json(ctxHash)) if !ctxHash.empty?
         
     | 
| 
       9 
10 
     | 
    
         
             
                    Sidekiq.logger.warn "#{ex.class.name}: #{ex.message}"
         
     | 
| 
       10 
11 
     | 
    
         
             
                    Sidekiq.logger.warn ex.backtrace.join("\n") unless ex.backtrace.nil?
         
     | 
| 
       11 
12 
     | 
    
         
             
                  end
         
     | 
    
        data/lib/sidekiq/fetch.rb
    CHANGED
    
    
    
        data/lib/sidekiq/launcher.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            # encoding: utf-8
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'sidekiq/manager'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'sidekiq/fetch'
         
     | 
| 
         @@ -79,7 +80,7 @@ module Sidekiq 
     | 
|
| 
       79 
80 
     | 
    
         
             
                    workers_key = "#{key}:workers".freeze
         
     | 
| 
       80 
81 
     | 
    
         
             
                    nowdate = Time.now.utc.strftime("%Y-%m-%d".freeze)
         
     | 
| 
       81 
82 
     | 
    
         
             
                    Sidekiq.redis do |conn|
         
     | 
| 
       82 
     | 
    
         
            -
                      conn. 
     | 
| 
      
 83 
     | 
    
         
            +
                      conn.multi do
         
     | 
| 
       83 
84 
     | 
    
         
             
                        conn.incrby("stat:processed".freeze, procd)
         
     | 
| 
       84 
85 
     | 
    
         
             
                        conn.incrby("stat:processed:#{nowdate}", procd)
         
     | 
| 
       85 
86 
     | 
    
         
             
                        conn.incrby("stat:failed".freeze, fails)
         
     | 
| 
         @@ -88,19 +89,24 @@ module Sidekiq 
     | 
|
| 
       88 
89 
     | 
    
         
             
                        Processor::WORKER_STATE.each_pair do |tid, hash|
         
     | 
| 
       89 
90 
     | 
    
         
             
                          conn.hset(workers_key, tid, Sidekiq.dump_json(hash))
         
     | 
| 
       90 
91 
     | 
    
         
             
                        end
         
     | 
| 
      
 92 
     | 
    
         
            +
                        conn.expire(workers_key, 60)
         
     | 
| 
       91 
93 
     | 
    
         
             
                      end
         
     | 
| 
       92 
94 
     | 
    
         
             
                    end
         
     | 
| 
       93 
95 
     | 
    
         
             
                    fails = procd = 0
         
     | 
| 
       94 
96 
     | 
    
         | 
| 
       95 
     | 
    
         
            -
                    _, _, _, msg = Sidekiq.redis do |conn|
         
     | 
| 
       96 
     | 
    
         
            -
                      conn. 
     | 
| 
      
 97 
     | 
    
         
            +
                    _, exists, _, _, msg = Sidekiq.redis do |conn|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      conn.multi do
         
     | 
| 
       97 
99 
     | 
    
         
             
                        conn.sadd('processes', key)
         
     | 
| 
      
 100 
     | 
    
         
            +
                        conn.exists(key)
         
     | 
| 
       98 
101 
     | 
    
         
             
                        conn.hmset(key, 'info', json, 'busy', Processor::WORKER_STATE.size, 'beat', Time.now.to_f, 'quiet', @done)
         
     | 
| 
       99 
102 
     | 
    
         
             
                        conn.expire(key, 60)
         
     | 
| 
       100 
103 
     | 
    
         
             
                        conn.rpop("#{key}-signals")
         
     | 
| 
       101 
104 
     | 
    
         
             
                      end
         
     | 
| 
       102 
105 
     | 
    
         
             
                    end
         
     | 
| 
       103 
106 
     | 
    
         | 
| 
      
 107 
     | 
    
         
            +
                    # first heartbeat or recovering from an outage and need to reestablish our heartbeat
         
     | 
| 
      
 108 
     | 
    
         
            +
                    fire_event(:heartbeat) if !exists
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
       104 
110 
     | 
    
         
             
                    return unless msg
         
     | 
| 
       105 
111 
     | 
    
         | 
| 
       106 
112 
     | 
    
         
             
                    if JVM_RESERVED_SIGNALS.include?(msg)
         
     | 
    
        data/lib/sidekiq/logging.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'time'
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'logger'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'fcntl'
         
     | 
| 
         @@ -47,7 +48,7 @@ module Sidekiq 
     | 
|
| 
       47 
48 
     | 
    
         
             
                end
         
     | 
| 
       48 
49 
     | 
    
         | 
| 
       49 
50 
     | 
    
         
             
                def self.logger=(log)
         
     | 
| 
       50 
     | 
    
         
            -
                  @logger = (log ? log : Logger.new( 
     | 
| 
      
 51 
     | 
    
         
            +
                  @logger = (log ? log : Logger.new(File::NULL))
         
     | 
| 
       51 
52 
     | 
    
         
             
                end
         
     | 
| 
       52 
53 
     | 
    
         | 
| 
       53 
54 
     | 
    
         
             
                # This reopens ALL logfiles in the process that have been rotated
         
     | 
    
        data/lib/sidekiq/manager.rb
    CHANGED
    
    
| 
         @@ -8,14 +8,14 @@ module Sidekiq 
     | 
|
| 
       8 
8 
     | 
    
         
             
                  # Automatically retry jobs that fail in Sidekiq.
         
     | 
| 
       9 
9 
     | 
    
         
             
                  # Sidekiq's retry support assumes a typical development lifecycle:
         
     | 
| 
       10 
10 
     | 
    
         
             
                  #
         
     | 
| 
       11 
     | 
    
         
            -
                  #   0.  
     | 
| 
       12 
     | 
    
         
            -
                  #   1.  
     | 
| 
       13 
     | 
    
         
            -
                  #      the job and pushes it onto a retry queue
         
     | 
| 
       14 
     | 
    
         
            -
                  #   2.  
     | 
| 
       15 
     | 
    
         
            -
                  #      an exponential delay, the job continues to fail
         
     | 
| 
       16 
     | 
    
         
            -
                  #   3.  
     | 
| 
      
 11 
     | 
    
         
            +
                  #   0. Push some code changes with a bug in it.
         
     | 
| 
      
 12 
     | 
    
         
            +
                  #   1. Bug causes job processing to fail, Sidekiq's middleware captures
         
     | 
| 
      
 13 
     | 
    
         
            +
                  #      the job and pushes it onto a retry queue.
         
     | 
| 
      
 14 
     | 
    
         
            +
                  #   2. Sidekiq retries jobs in the retry queue multiple times with
         
     | 
| 
      
 15 
     | 
    
         
            +
                  #      an exponential delay, the job continues to fail.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  #   3. After a few days, a developer deploys a fix. The job is
         
     | 
| 
       17 
17 
     | 
    
         
             
                  #      reprocessed successfully.
         
     | 
| 
       18 
     | 
    
         
            -
                  #   4.  
     | 
| 
      
 18 
     | 
    
         
            +
                  #   4. Once retries are exhausted, Sidekiq will give up and move the
         
     | 
| 
       19 
19 
     | 
    
         
             
                  #      job to the Dead Job Queue (aka morgue) where it must be dealt with
         
     | 
| 
       20 
20 
     | 
    
         
             
                  #      manually in the Web UI.
         
     | 
| 
       21 
21 
     | 
    
         
             
                  #   5. After 6 months on the DJQ, Sidekiq will discard the job.
         
     | 
    
        data/lib/sidekiq/paginator.rb
    CHANGED
    
    
    
        data/lib/sidekiq/processor.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'sidekiq/util'
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'sidekiq/fetch'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'thread'
         
     | 
| 
         @@ -35,6 +36,7 @@ module Sidekiq 
     | 
|
| 
       35 
36 
     | 
    
         
             
                  @job = nil
         
     | 
| 
       36 
37 
     | 
    
         
             
                  @thread = nil
         
     | 
| 
       37 
38 
     | 
    
         
             
                  @strategy = (mgr.options[:fetch] || Sidekiq::BasicFetch).new(mgr.options)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  @reloader = Sidekiq.options[:reloader]
         
     | 
| 
       38 
40 
     | 
    
         
             
                end
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
       40 
42 
     | 
    
         
             
                def terminate(wait=false)
         
     | 
| 
         @@ -117,33 +119,35 @@ module Sidekiq 
     | 
|
| 
       117 
119 
     | 
    
         
             
                  jobstr = work.job
         
     | 
| 
       118 
120 
     | 
    
         
             
                  queue = work.queue_name
         
     | 
| 
       119 
121 
     | 
    
         | 
| 
       120 
     | 
    
         
            -
                   
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
       122 
     | 
    
         
            -
                     
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
       124 
     | 
    
         
            -
             
     | 
| 
       125 
     | 
    
         
            -
             
     | 
| 
       126 
     | 
    
         
            -
             
     | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
                       
     | 
| 
       129 
     | 
    
         
            -
                         
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 122 
     | 
    
         
            +
                  @reloader.call do
         
     | 
| 
      
 123 
     | 
    
         
            +
                    ack = false
         
     | 
| 
      
 124 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 125 
     | 
    
         
            +
                      job = Sidekiq.load_json(jobstr)
         
     | 
| 
      
 126 
     | 
    
         
            +
                      klass  = job['class'.freeze].constantize
         
     | 
| 
      
 127 
     | 
    
         
            +
                      worker = klass.new
         
     | 
| 
      
 128 
     | 
    
         
            +
                      worker.jid = job['jid'.freeze]
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                      stats(worker, job, queue) do
         
     | 
| 
      
 131 
     | 
    
         
            +
                        Sidekiq.server_middleware.invoke(worker, job, queue) do
         
     | 
| 
      
 132 
     | 
    
         
            +
                          # Only ack if we either attempted to start this job or
         
     | 
| 
      
 133 
     | 
    
         
            +
                          # successfully completed it. This prevents us from
         
     | 
| 
      
 134 
     | 
    
         
            +
                          # losing jobs if a middleware raises an exception before yielding
         
     | 
| 
      
 135 
     | 
    
         
            +
                          ack = true
         
     | 
| 
      
 136 
     | 
    
         
            +
                          execute_job(worker, cloned(job['args'.freeze]))
         
     | 
| 
      
 137 
     | 
    
         
            +
                        end
         
     | 
| 
       134 
138 
     | 
    
         
             
                      end
         
     | 
| 
      
 139 
     | 
    
         
            +
                      ack = true
         
     | 
| 
      
 140 
     | 
    
         
            +
                    rescue Sidekiq::Shutdown
         
     | 
| 
      
 141 
     | 
    
         
            +
                      # Had to force kill this job because it didn't finish
         
     | 
| 
      
 142 
     | 
    
         
            +
                      # within the timeout.  Don't acknowledge the work since
         
     | 
| 
      
 143 
     | 
    
         
            +
                      # we didn't properly finish it.
         
     | 
| 
      
 144 
     | 
    
         
            +
                      ack = false
         
     | 
| 
      
 145 
     | 
    
         
            +
                    rescue Exception => ex
         
     | 
| 
      
 146 
     | 
    
         
            +
                      handle_exception(ex, job || { :job => jobstr })
         
     | 
| 
      
 147 
     | 
    
         
            +
                      raise
         
     | 
| 
      
 148 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 149 
     | 
    
         
            +
                      work.acknowledge if ack
         
     | 
| 
       135 
150 
     | 
    
         
             
                    end
         
     | 
| 
       136 
     | 
    
         
            -
                    ack = true
         
     | 
| 
       137 
     | 
    
         
            -
                  rescue Sidekiq::Shutdown
         
     | 
| 
       138 
     | 
    
         
            -
                    # Had to force kill this job because it didn't finish
         
     | 
| 
       139 
     | 
    
         
            -
                    # within the timeout.  Don't acknowledge the work since
         
     | 
| 
       140 
     | 
    
         
            -
                    # we didn't properly finish it.
         
     | 
| 
       141 
     | 
    
         
            -
                    ack = false
         
     | 
| 
       142 
     | 
    
         
            -
                  rescue Exception => ex
         
     | 
| 
       143 
     | 
    
         
            -
                    handle_exception(ex, job || { :job => jobstr })
         
     | 
| 
       144 
     | 
    
         
            -
                    raise
         
     | 
| 
       145 
     | 
    
         
            -
                  ensure
         
     | 
| 
       146 
     | 
    
         
            -
                    work.acknowledge if ack
         
     | 
| 
       147 
151 
     | 
    
         
             
                  end
         
     | 
| 
       148 
152 
     | 
    
         
             
                end
         
     | 
| 
       149 
153 
     | 
    
         | 
    
        data/lib/sidekiq/rails.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            module Sidekiq
         
     | 
| 
       2 
3 
     | 
    
         
             
              def self.hook_rails!
         
     | 
| 
       3 
4 
     | 
    
         
             
                return if defined?(@delay_removed)
         
     | 
| 
         @@ -34,5 +35,22 @@ module Sidekiq 
     | 
|
| 
       34 
35 
     | 
    
         
             
                initializer 'sidekiq' do
         
     | 
| 
       35 
36 
     | 
    
         
             
                  Sidekiq.hook_rails!
         
     | 
| 
       36 
37 
     | 
    
         
             
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                class Reloader
         
     | 
| 
      
 40 
     | 
    
         
            +
                  def initialize(app = ::Rails.application)
         
     | 
| 
      
 41 
     | 
    
         
            +
                    Sidekiq.logger.debug "Enabling Rails 5+ live code reloading, so hot!" unless app.config.cache_classes
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @app = app
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def call
         
     | 
| 
      
 46 
     | 
    
         
            +
                    @app.reloader.wrap do
         
     | 
| 
      
 47 
     | 
    
         
            +
                      yield
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  def inspect
         
     | 
| 
      
 52 
     | 
    
         
            +
                    "#<Sidekiq::Rails::Reloader @app=#{@app.class.name}>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
       37 
55 
     | 
    
         
             
              end if defined?(::Rails)
         
     | 
| 
       38 
56 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'connection_pool'
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'redis'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'uri'
         
     | 
| 
         @@ -7,6 +8,8 @@ module Sidekiq 
     | 
|
| 
       7 
8 
     | 
    
         
             
                class << self
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
                  def create(options={})
         
     | 
| 
      
 11 
     | 
    
         
            +
                    options = options.symbolize_keys
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       10 
13 
     | 
    
         
             
                    options[:url] ||= determine_redis_provider
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
15 
     | 
    
         
             
                    size = options[:size] || (Sidekiq.server? ? (Sidekiq.options[:concurrency] + 5) : 5)
         
     | 
| 
         @@ -32,7 +35,7 @@ module Sidekiq 
     | 
|
| 
       32 
35 
     | 
    
         
             
                  #   - enterprise's leader election
         
     | 
| 
       33 
36 
     | 
    
         
             
                  #   - enterprise's cron support
         
     | 
| 
       34 
37 
     | 
    
         
             
                  def verify_sizing(size, concurrency)
         
     | 
| 
       35 
     | 
    
         
            -
                    raise ArgumentError, "Your Redis connection pool is too small for Sidekiq to work 
     | 
| 
      
 38 
     | 
    
         
            +
                    raise ArgumentError, "Your Redis connection pool is too small for Sidekiq to work. Your pool has #{size} connections but really needs to have at least #{concurrency + 2}" if size <= concurrency
         
     | 
| 
       36 
39 
     | 
    
         
             
                  end
         
     | 
| 
       37 
40 
     | 
    
         | 
| 
       38 
41 
     | 
    
         
             
                  def build_client(options)
         
     | 
| 
         @@ -44,8 +47,8 @@ module Sidekiq 
     | 
|
| 
       44 
47 
     | 
    
         
             
                        require 'redis/namespace'
         
     | 
| 
       45 
48 
     | 
    
         
             
                        Redis::Namespace.new(namespace, :redis => client)
         
     | 
| 
       46 
49 
     | 
    
         
             
                      rescue LoadError
         
     | 
| 
       47 
     | 
    
         
            -
                        Sidekiq.logger.error("Your Redis configuration  
     | 
| 
       48 
     | 
    
         
            -
                                             "Add the gem to your Gemfile  
     | 
| 
      
 50 
     | 
    
         
            +
                        Sidekiq.logger.error("Your Redis configuration uses the namespace '#{namespace}' but the redis-namespace gem is not included in the Gemfile." \
         
     | 
| 
      
 51 
     | 
    
         
            +
                                             "Add the gem to your Gemfile to continue using a namespace. Otherwise, remove the namespace parameter.")
         
     | 
| 
       49 
52 
     | 
    
         
             
                        exit(-127)
         
     | 
| 
       50 
53 
     | 
    
         
             
                      end
         
     | 
| 
       51 
54 
     | 
    
         
             
                    else
         
     | 
    
        data/lib/sidekiq/scheduled.rb
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'sidekiq'
         
     | 
| 
       2 
3 
     | 
    
         
             
            require 'sidekiq/util'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'sidekiq/api'
         
     | 
| 
         @@ -45,6 +46,7 @@ module Sidekiq 
     | 
|
| 
       45 
46 
     | 
    
         
             
                    @enq = (Sidekiq.options[:scheduled_enq] || Sidekiq::Scheduled::Enq).new
         
     | 
| 
       46 
47 
     | 
    
         
             
                    @sleeper = ConnectionPool::TimedStack.new
         
     | 
| 
       47 
48 
     | 
    
         
             
                    @done = false
         
     | 
| 
      
 49 
     | 
    
         
            +
                    @thread = nil
         
     | 
| 
       48 
50 
     | 
    
         
             
                  end
         
     | 
| 
       49 
51 
     | 
    
         | 
| 
       50 
52 
     | 
    
         
             
                  # Shut down this instance, will pause until the thread is dead.
         
     | 
    
        data/lib/sidekiq/testing.rb
    CHANGED
    
    
    
        data/lib/sidekiq/util.rb
    CHANGED
    
    
    
        data/lib/sidekiq/version.rb
    CHANGED
    
    
    
        data/lib/sidekiq/web.rb
    CHANGED
    
    | 
         @@ -1,25 +1,28 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       1 
2 
     | 
    
         
             
            require 'erb'
         
     | 
| 
       2 
     | 
    
         
            -
            require 'yaml'
         
     | 
| 
       3 
     | 
    
         
            -
            require 'sinatra/base'
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
4 
     | 
    
         
             
            require 'sidekiq'
         
     | 
| 
       6 
5 
     | 
    
         
             
            require 'sidekiq/api'
         
     | 
| 
       7 
6 
     | 
    
         
             
            require 'sidekiq/paginator'
         
     | 
| 
       8 
     | 
    
         
            -
            require 'sidekiq/ 
     | 
| 
      
 7 
     | 
    
         
            +
            require 'sidekiq/web/helpers'
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
            require 'sidekiq/web/router'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require 'sidekiq/web/action'
         
     | 
| 
      
 11 
     | 
    
         
            +
            require 'sidekiq/web/application'
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                use ::Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'
         
     | 
| 
      
 13 
     | 
    
         
            +
            require 'rack/protection'
         
     | 
| 
       16 
14 
     | 
    
         | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
                set :locales, ["#{root}/locales"]
         
     | 
| 
      
 15 
     | 
    
         
            +
            require 'rack/builder'
         
     | 
| 
      
 16 
     | 
    
         
            +
            require 'rack/file'
         
     | 
| 
      
 17 
     | 
    
         
            +
            require 'rack/session/cookie'
         
     | 
| 
       21 
18 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
            module Sidekiq
         
     | 
| 
      
 20 
     | 
    
         
            +
              class Web
         
     | 
| 
      
 21 
     | 
    
         
            +
                ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../web")
         
     | 
| 
      
 22 
     | 
    
         
            +
                VIEWS = "#{ROOT}/views".freeze
         
     | 
| 
      
 23 
     | 
    
         
            +
                LOCALES = ["#{ROOT}/locales".freeze]
         
     | 
| 
      
 24 
     | 
    
         
            +
                LAYOUT = "#{VIEWS}/layout.erb".freeze
         
     | 
| 
      
 25 
     | 
    
         
            +
                ASSETS = "#{ROOT}/assets".freeze
         
     | 
| 
       23 
26 
     | 
    
         | 
| 
       24 
27 
     | 
    
         
             
                DEFAULT_TABS = {
         
     | 
| 
       25 
28 
     | 
    
         
             
                  "Dashboard" => '',
         
     | 
| 
         @@ -31,6 +34,18 @@ module Sidekiq 
     | 
|
| 
       31 
34 
     | 
    
         
             
                }
         
     | 
| 
       32 
35 
     | 
    
         | 
| 
       33 
36 
     | 
    
         
             
                class << self
         
     | 
| 
      
 37 
     | 
    
         
            +
                  def settings
         
     | 
| 
      
 38 
     | 
    
         
            +
                    self
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def middlewares
         
     | 
| 
      
 42 
     | 
    
         
            +
                    @middlewares ||= []
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def use(*middleware_args, &block)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    middlewares << [middleware_args, block]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       34 
49 
     | 
    
         
             
                  def default_tabs
         
     | 
| 
       35 
50 
     | 
    
         
             
                    DEFAULT_TABS
         
     | 
| 
       36 
51 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -40,234 +55,97 @@ module Sidekiq 
     | 
|
| 
       40 
55 
     | 
    
         
             
                  end
         
     | 
| 
       41 
56 
     | 
    
         
             
                  alias_method :tabs, :custom_tabs
         
     | 
| 
       42 
57 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                   
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                get "/busy" do
         
     | 
| 
       47 
     | 
    
         
            -
                  erb :busy
         
     | 
| 
       48 
     | 
    
         
            -
                end
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
                post "/busy" do
         
     | 
| 
       51 
     | 
    
         
            -
                  if params['identity']
         
     | 
| 
       52 
     | 
    
         
            -
                    p = Sidekiq::Process.new('identity' => params['identity'])
         
     | 
| 
       53 
     | 
    
         
            -
                    p.quiet! if params[:quiet]
         
     | 
| 
       54 
     | 
    
         
            -
                    p.stop! if params[:stop]
         
     | 
| 
       55 
     | 
    
         
            -
                  else
         
     | 
| 
       56 
     | 
    
         
            -
                    processes.each do |pro|
         
     | 
| 
       57 
     | 
    
         
            -
                      pro.quiet! if params[:quiet]
         
     | 
| 
       58 
     | 
    
         
            -
                      pro.stop! if params[:stop]
         
     | 
| 
       59 
     | 
    
         
            -
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  def locales
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @locales ||= LOCALES
         
     | 
| 
       60 
60 
     | 
    
         
             
                  end
         
     | 
| 
       61 
     | 
    
         
            -
                  redirect "#{root_path}busy"
         
     | 
| 
       62 
     | 
    
         
            -
                end
         
     | 
| 
       63 
61 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                  erb :queues
         
     | 
| 
       67 
     | 
    
         
            -
                end
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                get "/queues/:name" do
         
     | 
| 
       70 
     | 
    
         
            -
                  halt 404 unless params[:name]
         
     | 
| 
       71 
     | 
    
         
            -
                  @count = (params[:count] || 25).to_i
         
     | 
| 
       72 
     | 
    
         
            -
                  @name = params[:name]
         
     | 
| 
       73 
     | 
    
         
            -
                  @queue = Sidekiq::Queue.new(@name)
         
     | 
| 
       74 
     | 
    
         
            -
                  (@current_page, @total_size, @messages) = page("queue:#{@name}", params[:page], @count)
         
     | 
| 
       75 
     | 
    
         
            -
                  @messages = @messages.map { |msg| Sidekiq::Job.new(msg, @name) }
         
     | 
| 
       76 
     | 
    
         
            -
                  erb :queue
         
     | 
| 
       77 
     | 
    
         
            -
                end
         
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
                post "/queues/:name" do
         
     | 
| 
       80 
     | 
    
         
            -
                  Sidekiq::Queue.new(params[:name]).clear
         
     | 
| 
       81 
     | 
    
         
            -
                  redirect "#{root_path}queues"
         
     | 
| 
       82 
     | 
    
         
            -
                end
         
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                post "/queues/:name/delete" do
         
     | 
| 
       85 
     | 
    
         
            -
                  Sidekiq::Job.new(params[:key_val], params[:name]).delete
         
     | 
| 
       86 
     | 
    
         
            -
                  redirect_with_query("#{root_path}queues/#{params[:name]}")
         
     | 
| 
       87 
     | 
    
         
            -
                end
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                get '/morgue' do
         
     | 
| 
       90 
     | 
    
         
            -
                  @count = (params[:count] || 25).to_i
         
     | 
| 
       91 
     | 
    
         
            -
                  (@current_page, @total_size, @dead) = page("dead", params[:page], @count, reverse: true)
         
     | 
| 
       92 
     | 
    
         
            -
                  @dead = @dead.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
         
     | 
| 
       93 
     | 
    
         
            -
                  erb :morgue
         
     | 
| 
       94 
     | 
    
         
            -
                end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
                get "/morgue/:key" do
         
     | 
| 
       97 
     | 
    
         
            -
                  halt 404 unless params['key']
         
     | 
| 
       98 
     | 
    
         
            -
                  @dead = Sidekiq::DeadSet.new.fetch(*parse_params(params['key'])).first
         
     | 
| 
       99 
     | 
    
         
            -
                  redirect "#{root_path}morgue" if @dead.nil?
         
     | 
| 
       100 
     | 
    
         
            -
                  erb :dead
         
     | 
| 
       101 
     | 
    
         
            -
                end
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                post '/morgue' do
         
     | 
| 
       104 
     | 
    
         
            -
                  redirect request.path unless params['key']
         
     | 
| 
       105 
     | 
    
         
            -
             
     | 
| 
       106 
     | 
    
         
            -
                  params['key'].each do |key|
         
     | 
| 
       107 
     | 
    
         
            -
                    job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
         
     | 
| 
       108 
     | 
    
         
            -
                    retry_or_delete_or_kill job, params if job
         
     | 
| 
      
 62 
     | 
    
         
            +
                  def views
         
     | 
| 
      
 63 
     | 
    
         
            +
                    @views ||= VIEWS
         
     | 
| 
       109 
64 
     | 
    
         
             
                  end
         
     | 
| 
       110 
     | 
    
         
            -
                  redirect_with_query("#{root_path}morgue")
         
     | 
| 
       111 
     | 
    
         
            -
                end
         
     | 
| 
       112 
65 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                   
     | 
| 
       115 
     | 
    
         
            -
                  redirect "#{root_path}morgue"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  attr_accessor :app_url, :session_secret, :redis_pool
         
     | 
| 
      
 67 
     | 
    
         
            +
                  attr_writer :locales, :views
         
     | 
| 
       116 
68 
     | 
    
         
             
                end
         
     | 
| 
       117 
69 
     | 
    
         | 
| 
       118 
     | 
    
         
            -
                 
     | 
| 
       119 
     | 
    
         
            -
                   
     | 
| 
       120 
     | 
    
         
            -
                  redirect "#{root_path}morgue"
         
     | 
| 
      
 70 
     | 
    
         
            +
                def settings
         
     | 
| 
      
 71 
     | 
    
         
            +
                  self.class.settings
         
     | 
| 
       121 
72 
     | 
    
         
             
                end
         
     | 
| 
       122 
73 
     | 
    
         | 
| 
       123 
     | 
    
         
            -
                 
     | 
| 
       124 
     | 
    
         
            -
                   
     | 
| 
       125 
     | 
    
         
            -
                  job = Sidekiq::DeadSet.new.fetch(*parse_params(params['key'])).first
         
     | 
| 
       126 
     | 
    
         
            -
                  retry_or_delete_or_kill job, params if job
         
     | 
| 
       127 
     | 
    
         
            -
                  redirect_with_query("#{root_path}morgue")
         
     | 
| 
      
 74 
     | 
    
         
            +
                def use(*middleware_args, &block)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  middlewares << [middleware_args, block]
         
     | 
| 
       128 
76 
     | 
    
         
             
                end
         
     | 
| 
       129 
77 
     | 
    
         | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                  @count = (params[:count] || 25).to_i
         
     | 
| 
       133 
     | 
    
         
            -
                  (@current_page, @total_size, @retries) = page("retry", params[:page], @count)
         
     | 
| 
       134 
     | 
    
         
            -
                  @retries = @retries.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
         
     | 
| 
       135 
     | 
    
         
            -
                  erb :retries
         
     | 
| 
       136 
     | 
    
         
            -
                end
         
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
                get "/retries/:key" do
         
     | 
| 
       139 
     | 
    
         
            -
                  @retry = Sidekiq::RetrySet.new.fetch(*parse_params(params['key'])).first
         
     | 
| 
       140 
     | 
    
         
            -
                  redirect "#{root_path}retries" if @retry.nil?
         
     | 
| 
       141 
     | 
    
         
            -
                  erb :retry
         
     | 
| 
       142 
     | 
    
         
            -
                end
         
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
                post '/retries' do
         
     | 
| 
       145 
     | 
    
         
            -
                  redirect request.path unless params['key']
         
     | 
| 
       146 
     | 
    
         
            -
             
     | 
| 
       147 
     | 
    
         
            -
                  params['key'].each do |key|
         
     | 
| 
       148 
     | 
    
         
            -
                    job = Sidekiq::RetrySet.new.fetch(*parse_params(key)).first
         
     | 
| 
       149 
     | 
    
         
            -
                    retry_or_delete_or_kill job, params if job
         
     | 
| 
       150 
     | 
    
         
            -
                  end
         
     | 
| 
       151 
     | 
    
         
            -
                  redirect_with_query("#{root_path}retries")
         
     | 
| 
      
 78 
     | 
    
         
            +
                def middlewares
         
     | 
| 
      
 79 
     | 
    
         
            +
                  @middlewares ||= Web.middlewares.dup
         
     | 
| 
       152 
80 
     | 
    
         
             
                end
         
     | 
| 
       153 
81 
     | 
    
         | 
| 
       154 
     | 
    
         
            -
                 
     | 
| 
       155 
     | 
    
         
            -
                   
     | 
| 
       156 
     | 
    
         
            -
                  redirect "#{root_path}retries"
         
     | 
| 
      
 82 
     | 
    
         
            +
                def call(env)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  app.call(env)
         
     | 
| 
       157 
84 
     | 
    
         
             
                end
         
     | 
| 
       158 
85 
     | 
    
         | 
| 
       159 
     | 
    
         
            -
                 
     | 
| 
       160 
     | 
    
         
            -
                   
     | 
| 
       161 
     | 
    
         
            -
                   
     | 
| 
      
 86 
     | 
    
         
            +
                def self.call(env)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  @app ||= new
         
     | 
| 
      
 88 
     | 
    
         
            +
                  @app.call(env)
         
     | 
| 
       162 
89 
     | 
    
         
             
                end
         
     | 
| 
       163 
90 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                 
     | 
| 
       165 
     | 
    
         
            -
                   
     | 
| 
       166 
     | 
    
         
            -
                  retry_or_delete_or_kill job, params if job
         
     | 
| 
       167 
     | 
    
         
            -
                  redirect_with_query("#{root_path}retries")
         
     | 
| 
      
 91 
     | 
    
         
            +
                def app
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @app ||= build
         
     | 
| 
       168 
93 
     | 
    
         
             
                end
         
     | 
| 
       169 
94 
     | 
    
         | 
| 
       170 
     | 
    
         
            -
                 
     | 
| 
       171 
     | 
    
         
            -
                   
     | 
| 
       172 
     | 
    
         
            -
                  (@current_page, @total_size, @scheduled) = page("schedule", params[:page], @count)
         
     | 
| 
       173 
     | 
    
         
            -
                  @scheduled = @scheduled.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
         
     | 
| 
       174 
     | 
    
         
            -
                  erb :scheduled
         
     | 
| 
      
 95 
     | 
    
         
            +
                def self.register(extension)
         
     | 
| 
      
 96 
     | 
    
         
            +
                  extension.registered(WebApplication)
         
     | 
| 
       175 
97 
     | 
    
         
             
                end
         
     | 
| 
       176 
98 
     | 
    
         | 
| 
       177 
     | 
    
         
            -
                 
     | 
| 
       178 
     | 
    
         
            -
                  @job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
         
     | 
| 
       179 
     | 
    
         
            -
                  redirect "#{root_path}scheduled" if @job.nil?
         
     | 
| 
       180 
     | 
    
         
            -
                  erb :scheduled_job_info
         
     | 
| 
       181 
     | 
    
         
            -
                end
         
     | 
| 
       182 
     | 
    
         
            -
             
     | 
| 
       183 
     | 
    
         
            -
                post '/scheduled' do
         
     | 
| 
       184 
     | 
    
         
            -
                  redirect request.path unless params['key']
         
     | 
| 
      
 99 
     | 
    
         
            +
                private
         
     | 
| 
       185 
100 
     | 
    
         | 
| 
       186 
     | 
    
         
            -
             
     | 
| 
       187 
     | 
    
         
            -
             
     | 
| 
       188 
     | 
    
         
            -
                     
     | 
| 
      
 101 
     | 
    
         
            +
                def using?(middleware)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  middlewares.any? do |(m,_)|
         
     | 
| 
      
 103 
     | 
    
         
            +
                    m.kind_of?(Array) && (m[0] == middleware || m[0].kind_of?(middleware))
         
     | 
| 
       189 
104 
     | 
    
         
             
                  end
         
     | 
| 
       190 
     | 
    
         
            -
                  redirect_with_query("#{root_path}scheduled")
         
     | 
| 
       191 
     | 
    
         
            -
                end
         
     | 
| 
       192 
     | 
    
         
            -
             
     | 
| 
       193 
     | 
    
         
            -
                post "/scheduled/:key" do
         
     | 
| 
       194 
     | 
    
         
            -
                  halt 404 unless params['key']
         
     | 
| 
       195 
     | 
    
         
            -
                  job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
         
     | 
| 
       196 
     | 
    
         
            -
                  delete_or_add_queue job, params if job
         
     | 
| 
       197 
     | 
    
         
            -
                  redirect_with_query("#{root_path}scheduled")
         
     | 
| 
       198 
     | 
    
         
            -
                end
         
     | 
| 
       199 
     | 
    
         
            -
             
     | 
| 
       200 
     | 
    
         
            -
                get '/' do
         
     | 
| 
       201 
     | 
    
         
            -
                  @redis_info = redis_info.select{ |k, v| REDIS_KEYS.include? k }
         
     | 
| 
       202 
     | 
    
         
            -
                  stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
         
     | 
| 
       203 
     | 
    
         
            -
                  @processed_history = stats_history.processed
         
     | 
| 
       204 
     | 
    
         
            -
                  @failed_history = stats_history.failed
         
     | 
| 
       205 
     | 
    
         
            -
                  erb :dashboard
         
     | 
| 
       206 
105 
     | 
    
         
             
                end
         
     | 
| 
       207 
106 
     | 
    
         | 
| 
       208 
     | 
    
         
            -
                 
     | 
| 
      
 107 
     | 
    
         
            +
                def build
         
     | 
| 
      
 108 
     | 
    
         
            +
                  middlewares = self.middlewares
         
     | 
| 
      
 109 
     | 
    
         
            +
                  klass = self.class
         
     | 
| 
       209 
110 
     | 
    
         | 
| 
       210 
     | 
    
         
            -
             
     | 
| 
       211 
     | 
    
         
            -
             
     | 
| 
       212 
     | 
    
         
            -
             
     | 
| 
       213 
     | 
    
         
            -
             
     | 
| 
       214 
     | 
    
         
            -
                get '/stats' do
         
     | 
| 
       215 
     | 
    
         
            -
                  sidekiq_stats = Sidekiq::Stats.new
         
     | 
| 
       216 
     | 
    
         
            -
                  redis_stats   = redis_info.select { |k, v| REDIS_KEYS.include? k }
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
                  content_type :json
         
     | 
| 
       219 
     | 
    
         
            -
                  Sidekiq.dump_json(
         
     | 
| 
       220 
     | 
    
         
            -
                    sidekiq: {
         
     | 
| 
       221 
     | 
    
         
            -
                      processed:       sidekiq_stats.processed,
         
     | 
| 
       222 
     | 
    
         
            -
                      failed:          sidekiq_stats.failed,
         
     | 
| 
       223 
     | 
    
         
            -
                      busy:            sidekiq_stats.workers_size,
         
     | 
| 
       224 
     | 
    
         
            -
                      processes:       sidekiq_stats.processes_size,
         
     | 
| 
       225 
     | 
    
         
            -
                      enqueued:        sidekiq_stats.enqueued,
         
     | 
| 
       226 
     | 
    
         
            -
                      scheduled:       sidekiq_stats.scheduled_size,
         
     | 
| 
       227 
     | 
    
         
            -
                      retries:         sidekiq_stats.retry_size,
         
     | 
| 
       228 
     | 
    
         
            -
                      dead:            sidekiq_stats.dead_size,
         
     | 
| 
       229 
     | 
    
         
            -
                      default_latency: sidekiq_stats.default_queue_latency
         
     | 
| 
       230 
     | 
    
         
            -
                    },
         
     | 
| 
       231 
     | 
    
         
            -
                    redis: redis_stats
         
     | 
| 
       232 
     | 
    
         
            -
                  )
         
     | 
| 
       233 
     | 
    
         
            -
                end
         
     | 
| 
      
 111 
     | 
    
         
            +
                  unless using?(::Rack::Protection) || ENV['RACK_ENV'] == 'test'
         
     | 
| 
      
 112 
     | 
    
         
            +
                    middlewares.unshift [[::Rack::Protection, { use: :authenticity_token }], nil]
         
     | 
| 
      
 113 
     | 
    
         
            +
                  end
         
     | 
| 
       234 
114 
     | 
    
         | 
| 
       235 
     | 
    
         
            -
             
     | 
| 
       236 
     | 
    
         
            -
             
     | 
| 
      
 115 
     | 
    
         
            +
                  unless using? ::Rack::Session::Cookie
         
     | 
| 
      
 116 
     | 
    
         
            +
                    unless secret = Web.session_secret
         
     | 
| 
      
 117 
     | 
    
         
            +
                      require 'securerandom'
         
     | 
| 
      
 118 
     | 
    
         
            +
                      secret = SecureRandom.hex(64)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    end
         
     | 
| 
       237 
120 
     | 
    
         | 
| 
       238 
     | 
    
         
            -
             
     | 
| 
       239 
     | 
    
         
            -
                   
     | 
| 
       240 
     | 
    
         
            -
                    queue_stats.lengths
         
     | 
| 
       241 
     | 
    
         
            -
                  )
         
     | 
| 
       242 
     | 
    
         
            -
                end
         
     | 
| 
      
 121 
     | 
    
         
            +
                    middlewares.unshift [[::Rack::Session::Cookie, { secret: secret }], nil]
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
       243 
123 
     | 
    
         | 
| 
       244 
     | 
    
         
            -
             
     | 
| 
      
 124 
     | 
    
         
            +
                  ::Rack::Builder.new do
         
     | 
| 
      
 125 
     | 
    
         
            +
                    %w(stylesheets javascripts images).each do |asset_dir|
         
     | 
| 
      
 126 
     | 
    
         
            +
                      map "/#{asset_dir}" do
         
     | 
| 
      
 127 
     | 
    
         
            +
                        run ::Rack::File.new("#{ASSETS}/#{asset_dir}", { 'Cache-Control' => 'public, max-age=86400' })
         
     | 
| 
      
 128 
     | 
    
         
            +
                      end
         
     | 
| 
      
 129 
     | 
    
         
            +
                    end
         
     | 
| 
       245 
130 
     | 
    
         | 
| 
       246 
     | 
    
         
            -
             
     | 
| 
       247 
     | 
    
         
            -
                  if params['retry']
         
     | 
| 
       248 
     | 
    
         
            -
                    job.retry
         
     | 
| 
       249 
     | 
    
         
            -
                  elsif params['delete']
         
     | 
| 
       250 
     | 
    
         
            -
                    job.delete
         
     | 
| 
       251 
     | 
    
         
            -
                  elsif params['kill']
         
     | 
| 
       252 
     | 
    
         
            -
                    job.kill
         
     | 
| 
       253 
     | 
    
         
            -
                  end
         
     | 
| 
       254 
     | 
    
         
            -
                end
         
     | 
| 
      
 131 
     | 
    
         
            +
                    middlewares.each {|middleware, block| use(*middleware, &block) }
         
     | 
| 
       255 
132 
     | 
    
         | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
                  if params['delete']
         
     | 
| 
       258 
     | 
    
         
            -
                    job.delete
         
     | 
| 
       259 
     | 
    
         
            -
                  elsif params['add_to_queue']
         
     | 
| 
       260 
     | 
    
         
            -
                    job.add_to_queue
         
     | 
| 
      
 133 
     | 
    
         
            +
                    run WebApplication.new(klass)
         
     | 
| 
       261 
134 
     | 
    
         
             
                  end
         
     | 
| 
       262 
135 
     | 
    
         
             
                end
         
     | 
| 
       263 
136 
     | 
    
         
             
              end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
              Sidekiq::WebApplication.helpers WebHelpers
         
     | 
| 
      
 139 
     | 
    
         
            +
              Sidekiq::WebApplication.helpers Sidekiq::Paginator
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
              Sidekiq::WebAction.class_eval "def _render\n#{ERB.new(File.read(Web::LAYOUT)).src}\nend"
         
     | 
| 
       264 
142 
     | 
    
         
             
            end
         
     | 
| 
       265 
143 
     | 
    
         | 
| 
       266 
144 
     | 
    
         
             
            if defined?(::ActionDispatch::Request::Session) &&
         
     | 
| 
       267 
145 
     | 
    
         
             
                !::ActionDispatch::Request::Session.respond_to?(:each)
         
     | 
| 
       268 
146 
     | 
    
         
             
              # mperham/sidekiq#2460
         
     | 
| 
       269 
147 
     | 
    
         
             
              # Rack apps can't reuse the Rails session store without
         
     | 
| 
       270 
     | 
    
         
            -
              # this monkeypatch
         
     | 
| 
      
 148 
     | 
    
         
            +
              # this monkeypatch, fixed in Rails 5.
         
     | 
| 
       271 
149 
     | 
    
         
             
              class ActionDispatch::Request::Session
         
     | 
| 
       272 
150 
     | 
    
         
             
                def each(&block)
         
     | 
| 
       273 
151 
     | 
    
         
             
                  hash = self.to_hash
         
     |