sidekiq 5.1.1 → 5.2.10

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

Files changed (56) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +61 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +5 -8
  5. data/COMM-LICENSE +11 -9
  6. data/Changes.md +96 -0
  7. data/Ent-Changes.md +28 -0
  8. data/Gemfile +16 -5
  9. data/LICENSE +1 -1
  10. data/Pro-Changes.md +43 -0
  11. data/README.md +1 -1
  12. data/Rakefile +2 -1
  13. data/bin/sidekiqctl +13 -92
  14. data/bin/sidekiqload +1 -1
  15. data/lib/sidekiq/api.rb +62 -28
  16. data/lib/sidekiq/cli.rb +68 -61
  17. data/lib/sidekiq/client.rb +31 -30
  18. data/lib/sidekiq/ctl.rb +221 -0
  19. data/lib/sidekiq/delay.rb +1 -0
  20. data/lib/sidekiq/fetch.rb +1 -1
  21. data/lib/sidekiq/job_logger.rb +4 -3
  22. data/lib/sidekiq/job_retry.rb +40 -14
  23. data/lib/sidekiq/launcher.rb +19 -13
  24. data/lib/sidekiq/logging.rb +3 -3
  25. data/lib/sidekiq/manager.rb +3 -4
  26. data/lib/sidekiq/middleware/server/active_record.rb +2 -1
  27. data/lib/sidekiq/processor.rb +79 -28
  28. data/lib/sidekiq/rails.rb +4 -8
  29. data/lib/sidekiq/redis_connection.rb +29 -2
  30. data/lib/sidekiq/scheduled.rb +33 -4
  31. data/lib/sidekiq/testing.rb +4 -4
  32. data/lib/sidekiq/util.rb +1 -1
  33. data/lib/sidekiq/version.rb +1 -1
  34. data/lib/sidekiq/web/action.rb +2 -2
  35. data/lib/sidekiq/web/application.rb +28 -3
  36. data/lib/sidekiq/web/helpers.rb +14 -7
  37. data/lib/sidekiq/web/router.rb +10 -10
  38. data/lib/sidekiq/web.rb +4 -4
  39. data/lib/sidekiq/worker.rb +31 -15
  40. data/lib/sidekiq.rb +8 -7
  41. data/sidekiq.gemspec +5 -12
  42. data/web/assets/javascripts/application.js +0 -0
  43. data/web/assets/javascripts/dashboard.js +15 -5
  44. data/web/assets/stylesheets/application.css +35 -2
  45. data/web/assets/stylesheets/bootstrap.css +2 -2
  46. data/web/locales/ar.yml +1 -0
  47. data/web/locales/en.yml +1 -0
  48. data/web/locales/es.yml +3 -3
  49. data/web/views/_footer.erb +3 -0
  50. data/web/views/_nav.erb +3 -17
  51. data/web/views/layout.erb +1 -1
  52. data/web/views/queue.erb +1 -0
  53. data/web/views/queues.erb +1 -1
  54. data/web/views/retries.erb +4 -0
  55. metadata +19 -87
  56. data/lib/sidekiq/middleware/server/active_record_cache.rb +0 -11
data/lib/sidekiq/rails.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Sidekiq
3
4
  class Rails < ::Rails::Engine
4
5
  # We need to setup this up before any application configuration which might
@@ -9,15 +10,10 @@ module Sidekiq
9
10
  # class block. Definitely before config/environments/*.rb and
10
11
  # config/initializers/*.rb.
11
12
  config.before_configuration do
12
- if defined?(::ActiveRecord)
13
+ if ::Rails::VERSION::MAJOR < 5 && defined?(::ActiveRecord)
13
14
  Sidekiq.server_middleware do |chain|
14
- if ::Rails::VERSION::MAJOR < 5
15
- require 'sidekiq/middleware/server/active_record'
16
- chain.add Sidekiq::Middleware::Server::ActiveRecord
17
- end
18
-
19
- require 'sidekiq/middleware/server/active_record_cache'
20
- chain.add Sidekiq::Middleware::Server::ActiveRecordCache
15
+ require 'sidekiq/middleware/server/active_record'
16
+ chain.add Sidekiq::Middleware::Server::ActiveRecord
21
17
  end
22
18
  end
23
19
  end
@@ -15,7 +15,15 @@ module Sidekiq
15
15
  options[:id] = "Sidekiq-#{Sidekiq.server? ? "server" : "client"}-PID-#{$$}" if !options.has_key?(:id)
16
16
  options[:url] ||= determine_redis_provider
17
17
 
18
- size = options[:size] || (Sidekiq.server? ? (Sidekiq.options[:concurrency] + 5) : 5)
18
+ size = if options[:size]
19
+ options[:size]
20
+ elsif Sidekiq.server?
21
+ Sidekiq.options[:concurrency] + 5
22
+ elsif ENV['RAILS_MAX_THREADS']
23
+ Integer(ENV['RAILS_MAX_THREADS'])
24
+ else
25
+ 5
26
+ end
19
27
 
20
28
  verify_sizing(size, Sidekiq.options[:concurrency]) if Sidekiq.server?
21
29
 
@@ -70,7 +78,7 @@ module Sidekiq
70
78
  opts.delete(:network_timeout)
71
79
  end
72
80
 
73
- opts[:driver] ||= 'ruby'.freeze
81
+ opts[:driver] ||= Redis::Connection.drivers.last || 'ruby'
74
82
 
75
83
  # Issue #3303, redis-rb will silently retry an operation.
76
84
  # This can lead to duplicate jobs if Sidekiq::Client's LPUSH
@@ -107,6 +115,25 @@ module Sidekiq
107
115
  # REDIS_PROVIDER=MY_REDIS_URL
108
116
  # and Sidekiq will find your custom URL variable with no custom
109
117
  # initialization code at all.
118
+ p = ENV['REDIS_PROVIDER']
119
+ if p && p =~ /\:/
120
+ Sidekiq.logger.error <<-EOM
121
+
122
+ #################################################################################
123
+
124
+ REDIS_PROVIDER should be set to the **name** of the variable which contains the Redis URL, not a URL itself.
125
+ Platforms like Heroku sell addons that publish a *_URL variable. You tell Sidekiq with REDIS_PROVIDER, e.g.:
126
+
127
+ REDIS_PROVIDER=REDISTOGO_URL
128
+ REDISTOGO_URL=redis://somehost.example.com:6379/4
129
+
130
+ Use REDIS_URL if you wish to point Sidekiq to a URL directly.
131
+
132
+ This configuration error will crash starting in Sidekiq 5.3.
133
+
134
+ #################################################################################
135
+ EOM
136
+ end
110
137
  ENV[
111
138
  ENV['REDIS_PROVIDER'] || 'REDIS_URL'
112
139
  ]
@@ -17,7 +17,7 @@ module Sidekiq
17
17
  # We need to go through the list one at a time to reduce the risk of something
18
18
  # going wrong between the time jobs are popped from the scheduled queue and when
19
19
  # they are pushed onto a work queue and losing the jobs.
20
- while job = conn.zrangebyscore(sorted_set, '-inf'.freeze, now, :limit => [0, 1]).first do
20
+ while job = conn.zrangebyscore(sorted_set, '-inf', now, :limit => [0, 1]).first do
21
21
 
22
22
  # Pop item off the queue and add it to the work queue. If the job can't be popped from
23
23
  # the queue, it's because another process already popped it so we can move on to the
@@ -97,9 +97,34 @@ module Sidekiq
97
97
  sleep 5
98
98
  end
99
99
 
100
- # Calculates a random interval that is ±50% the desired average.
101
100
  def random_poll_interval
102
- poll_interval_average * rand + poll_interval_average.to_f / 2
101
+ # We want one Sidekiq process to schedule jobs every N seconds. We have M processes
102
+ # and **don't** want to coordinate.
103
+ #
104
+ # So in N*M second timespan, we want each process to schedule once. The basic loop is:
105
+ #
106
+ # * sleep a random amount within that N*M timespan
107
+ # * wake up and schedule
108
+ #
109
+ # We want to avoid one edge case: imagine a set of 2 processes, scheduling every 5 seconds,
110
+ # so N*M = 10. Each process decides to randomly sleep 8 seconds, now we've failed to meet
111
+ # that 5 second average. Thankfully each schedule cycle will sleep randomly so the next
112
+ # iteration could see each process sleep for 1 second, undercutting our average.
113
+ #
114
+ # So below 10 processes, we special case and ensure the processes sleep closer to the average.
115
+ # In the example above, each process should schedule every 10 seconds on average. We special
116
+ # case smaller clusters to add 50% so they would sleep somewhere between 5 and 15 seconds.
117
+ # As we run more processes, the scheduling interval average will approach an even spread
118
+ # between 0 and poll interval so we don't need this artifical boost.
119
+ #
120
+ if process_count < 10
121
+ # For small clusters, calculate a random interval that is ±50% the desired average.
122
+ poll_interval_average * rand + poll_interval_average.to_f / 2
123
+ else
124
+ # With 10+ processes, we should have enough randomness to get decent polling
125
+ # across the entire timespan
126
+ poll_interval_average * rand
127
+ end
103
128
  end
104
129
 
105
130
  # We do our best to tune the poll interval to the size of the active Sidekiq
@@ -123,9 +148,13 @@ module Sidekiq
123
148
  # This minimizes a single point of failure by dispersing check-ins but without taxing
124
149
  # Redis if you run many Sidekiq processes.
125
150
  def scaled_poll_interval
151
+ process_count * Sidekiq.options[:average_scheduled_poll_interval]
152
+ end
153
+
154
+ def process_count
126
155
  pcount = Sidekiq::ProcessSet.new.size
127
156
  pcount = 1 if pcount == 0
128
- pcount * Sidekiq.options[:average_scheduled_poll_interval]
157
+ pcount
129
158
  end
130
159
 
131
160
  def initial_wait
@@ -72,9 +72,7 @@ module Sidekiq
72
72
 
73
73
  class EmptyQueueError < RuntimeError; end
74
74
 
75
- class Client
76
- alias_method :raw_push_real, :raw_push
77
-
75
+ module TestingClient
78
76
  def raw_push(payloads)
79
77
  if Sidekiq::Testing.fake?
80
78
  payloads.each do |job|
@@ -92,11 +90,13 @@ module Sidekiq
92
90
  end
93
91
  true
94
92
  else
95
- raw_push_real(payloads)
93
+ super
96
94
  end
97
95
  end
98
96
  end
99
97
 
98
+ Sidekiq::Client.prepend TestingClient
99
+
100
100
  module Queues
101
101
  ##
102
102
  # The Queues class is only for testing the fake queue implementation.
data/lib/sidekiq/util.rb CHANGED
@@ -21,7 +21,7 @@ module Sidekiq
21
21
 
22
22
  def safe_thread(name, &block)
23
23
  Thread.new do
24
- Thread.current['sidekiq_label'.freeze] = name
24
+ Thread.current['sidekiq_label'] = name
25
25
  watchdog(name, &block)
26
26
  end
27
27
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Sidekiq
3
- VERSION = "5.1.1"
3
+ VERSION = "5.2.10"
4
4
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Sidekiq
4
4
  class WebAction
5
- RACK_SESSION = 'rack.session'.freeze
5
+ RACK_SESSION = 'rack.session'
6
6
 
7
7
  attr_accessor :env, :block, :type
8
8
 
@@ -15,7 +15,7 @@ module Sidekiq
15
15
  end
16
16
 
17
17
  def halt(res)
18
- throw :halt, res
18
+ throw :halt, [res, {"Content-Type" => "text/plain"}, [res.to_s]]
19
19
  end
20
20
 
21
21
  def redirect(location)
@@ -4,9 +4,24 @@ module Sidekiq
4
4
  class WebApplication
5
5
  extend WebRouter
6
6
 
7
- CONTENT_LENGTH = "Content-Length".freeze
8
- CONTENT_TYPE = "Content-Type".freeze
7
+ CONTENT_LENGTH = "Content-Length"
8
+ CONTENT_TYPE = "Content-Type"
9
9
  REDIS_KEYS = %w(redis_version uptime_in_days connected_clients used_memory_human used_memory_peak_human)
10
+ CSP_HEADER = [
11
+ "default-src 'self' https: http:",
12
+ "child-src 'self'",
13
+ "connect-src 'self' https: http: wss: ws:",
14
+ "font-src 'self' https: http:",
15
+ "frame-src 'self'",
16
+ "img-src 'self' https: http: data:",
17
+ "manifest-src 'self'",
18
+ "media-src 'self'",
19
+ "object-src 'none'",
20
+ "script-src 'self' https: http: 'unsafe-inline'",
21
+ "style-src 'self' https: http: 'unsafe-inline'",
22
+ "worker-src 'self'",
23
+ "base-uri 'self'"
24
+ ].join('; ').freeze
10
25
 
11
26
  def initialize(klass)
12
27
  @klass = klass
@@ -30,7 +45,10 @@ module Sidekiq
30
45
 
31
46
  get "/" do
32
47
  @redis_info = redis_info.select{ |k, v| REDIS_KEYS.include? k }
33
- stats_history = Sidekiq::Stats::History.new((params['days'] || 30).to_i)
48
+ days = (params["days"] || 30).to_i
49
+ return halt(401) if days < 1 || days > 180
50
+
51
+ stats_history = Sidekiq::Stats::History.new(days)
34
52
  @processed_history = stats_history.processed
35
53
  @failed_history = stats_history.failed
36
54
 
@@ -181,6 +199,12 @@ module Sidekiq
181
199
  redirect "#{root_path}retries"
182
200
  end
183
201
 
202
+ post "/retries/all/kill" do
203
+ Sidekiq::RetrySet.new.kill_all
204
+
205
+ redirect "#{root_path}retries"
206
+ end
207
+
184
208
  post "/retries/:key" do
185
209
  job = Sidekiq::RetrySet.new.fetch(*parse_params(route_params[:key])).first
186
210
 
@@ -279,6 +303,7 @@ module Sidekiq
279
303
  "Content-Type" => "text/html",
280
304
  "Cache-Control" => "no-cache",
281
305
  "Content-Language" => action.locale,
306
+ "Content-Security-Policy" => CSP_HEADER
282
307
  }
283
308
 
284
309
  [200, headers, [resp]]
@@ -80,7 +80,7 @@ module Sidekiq
80
80
 
81
81
  # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
82
82
  def user_preferred_languages
83
- languages = env['HTTP_ACCEPT_LANGUAGE'.freeze]
83
+ languages = env['HTTP_ACCEPT_LANGUAGE']
84
84
  languages.to_s.downcase.gsub(/\s+/, '').split(',').map do |language|
85
85
  locale, quality = language.split(';q=', 2)
86
86
  locale = nil if locale == '*' # Ignore wildcards
@@ -121,7 +121,7 @@ module Sidekiq
121
121
  end
122
122
 
123
123
  def t(msg, options={})
124
- string = get_locale[msg] || msg
124
+ string = get_locale[msg] || strings('en')[msg] || msg
125
125
  if options.empty?
126
126
  string
127
127
  else
@@ -155,7 +155,7 @@ module Sidekiq
155
155
  end
156
156
 
157
157
  def namespace
158
- @@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
158
+ @ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
159
159
  end
160
160
 
161
161
  def redis_info
@@ -184,7 +184,7 @@ module Sidekiq
184
184
  end
185
185
 
186
186
  def parse_params(params)
187
- score, jid = params.split("-")
187
+ score, jid = params.split("-", 2)
188
188
  [score.to_f, jid]
189
189
  end
190
190
 
@@ -207,9 +207,16 @@ module Sidekiq
207
207
  end
208
208
 
209
209
  def display_args(args, truncate_after_chars = 2000)
210
- args.map do |arg|
211
- h(truncate(to_display(arg), truncate_after_chars))
212
- end.join(", ")
210
+ return "Invalid job payload, args is nil" if args == nil
211
+ return "Invalid job payload, args must be an Array, not #{args.class.name}" if !args.is_a?(Array)
212
+
213
+ begin
214
+ args.map do |arg|
215
+ h(truncate(to_display(arg), truncate_after_chars))
216
+ end.join(", ")
217
+ rescue
218
+ "Illegal job arguments: #{h args.inspect}"
219
+ end
213
220
  end
214
221
 
215
222
  def csrf_tag
@@ -3,16 +3,16 @@ require 'rack'
3
3
 
4
4
  module Sidekiq
5
5
  module WebRouter
6
- GET = 'GET'.freeze
7
- DELETE = 'DELETE'.freeze
8
- POST = 'POST'.freeze
9
- PUT = 'PUT'.freeze
10
- PATCH = 'PATCH'.freeze
11
- HEAD = 'HEAD'.freeze
6
+ GET = 'GET'
7
+ DELETE = 'DELETE'
8
+ POST = 'POST'
9
+ PUT = 'PUT'
10
+ PATCH = 'PATCH'
11
+ HEAD = 'HEAD'
12
12
 
13
- ROUTE_PARAMS = 'rack.route_params'.freeze
14
- REQUEST_METHOD = 'REQUEST_METHOD'.freeze
15
- PATH_INFO = 'PATH_INFO'.freeze
13
+ ROUTE_PARAMS = 'rack.route_params'
14
+ REQUEST_METHOD = 'REQUEST_METHOD'
15
+ PATH_INFO = 'PATH_INFO'
16
16
 
17
17
  def get(path, &block)
18
18
  route(GET, path, &block)
@@ -64,7 +64,7 @@ module Sidekiq
64
64
  class WebRoute
65
65
  attr_accessor :request_method, :pattern, :block, :name
66
66
 
67
- NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^\.:$\/]+)/.freeze
67
+ NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^\.:$\/]+)/
68
68
 
69
69
  def initialize(request_method, pattern, block)
70
70
  @request_method = request_method
data/lib/sidekiq/web.rb CHANGED
@@ -19,10 +19,10 @@ require 'rack/session/cookie'
19
19
  module Sidekiq
20
20
  class Web
21
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
22
+ VIEWS = "#{ROOT}/views"
23
+ LOCALES = ["#{ROOT}/locales"]
24
+ LAYOUT = "#{VIEWS}/layout.erb"
25
+ ASSETS = "#{ROOT}/assets"
26
26
 
27
27
  DEFAULT_TABS = {
28
28
  "Dashboard" => '',
@@ -7,13 +7,13 @@ module Sidekiq
7
7
  # Include this module in your worker class and you can easily create
8
8
  # asynchronous jobs:
9
9
  #
10
- # class HardWorker
11
- # include Sidekiq::Worker
10
+ # class HardWorker
11
+ # include Sidekiq::Worker
12
12
  #
13
- # def perform(*args)
14
- # # do some work
13
+ # def perform(*args)
14
+ # # do some work
15
+ # end
15
16
  # end
16
- # end
17
17
  #
18
18
  # Then in your Rails app, you can do this:
19
19
  #
@@ -46,8 +46,13 @@ module Sidekiq
46
46
  @opts = opts
47
47
  end
48
48
 
49
+ def set(options)
50
+ @opts.merge!(options)
51
+ self
52
+ end
53
+
49
54
  def perform_async(*args)
50
- @klass.client_push(@opts.merge('args'.freeze => args, 'class'.freeze => @klass))
55
+ @klass.client_push(@opts.merge('args' => args, 'class' => @klass))
51
56
  end
52
57
 
53
58
  # +interval+ must be a timestamp, numeric or something that acts
@@ -57,15 +62,16 @@ module Sidekiq
57
62
  now = Time.now.to_f
58
63
  ts = (int < 1_000_000_000 ? now + int : int)
59
64
 
60
- payload = @opts.merge('class'.freeze => @klass, 'args'.freeze => args, 'at'.freeze => ts)
65
+ payload = @opts.merge('class' => @klass, 'args' => args, 'at' => ts)
61
66
  # Optimization to enqueue something now that is scheduled to go out now or in the past
62
- payload.delete('at'.freeze) if ts <= now
67
+ payload.delete('at') if ts <= now
63
68
  @klass.client_push(payload)
64
69
  end
65
70
  alias_method :perform_at, :perform_in
66
71
  end
67
72
 
68
73
  module ClassMethods
74
+ ACCESSOR_MUTEX = Mutex.new
69
75
 
70
76
  def delay(*args)
71
77
  raise ArgumentError, "Do not call .delay on a Sidekiq::Worker class, call .perform_async"
@@ -84,7 +90,7 @@ module Sidekiq
84
90
  end
85
91
 
86
92
  def perform_async(*args)
87
- client_push('class'.freeze => self, 'args'.freeze => args)
93
+ client_push('class' => self, 'args' => args)
88
94
  end
89
95
 
90
96
  # +interval+ must be a timestamp, numeric or something that acts
@@ -94,10 +100,10 @@ module Sidekiq
94
100
  now = Time.now.to_f
95
101
  ts = (int < 1_000_000_000 ? now + int : int)
96
102
 
97
- item = { 'class'.freeze => self, 'args'.freeze => args, 'at'.freeze => ts }
103
+ item = { 'class' => self, 'args' => args, 'at' => ts }
98
104
 
99
105
  # Optimization to enqueue something now that is scheduled to go out now or in the past
100
- item.delete('at'.freeze) if ts <= now
106
+ item.delete('at') if ts <= now
101
107
 
102
108
  client_push(item)
103
109
  end
@@ -134,7 +140,7 @@ module Sidekiq
134
140
  end
135
141
 
136
142
  def client_push(item) # :nodoc:
137
- pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options['pool'.freeze] || Sidekiq.redis_pool
143
+ pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options['pool'] || Sidekiq.redis_pool
138
144
  # stringify
139
145
  item.keys.each do |key|
140
146
  item[key.to_s] = item.delete(key)
@@ -148,10 +154,18 @@ module Sidekiq
148
154
  instance_writer = true
149
155
 
150
156
  attrs.each do |name|
157
+ synchronized_getter = "__synchronized_#{name}"
158
+
151
159
  singleton_class.instance_eval do
152
160
  undef_method(name) if method_defined?(name) || private_method_defined?(name)
153
161
  end
154
- define_singleton_method(name) { nil }
162
+
163
+ define_singleton_method(synchronized_getter) { nil }
164
+ singleton_class.class_eval do
165
+ private(synchronized_getter)
166
+ end
167
+
168
+ define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
155
169
 
156
170
  ivar = "@#{name}"
157
171
 
@@ -161,8 +175,10 @@ module Sidekiq
161
175
  end
162
176
  define_singleton_method("#{name}=") do |val|
163
177
  singleton_class.class_eval do
164
- undef_method(name) if method_defined?(name) || private_method_defined?(name)
165
- define_method(name) { val }
178
+ ACCESSOR_MUTEX.synchronize do
179
+ undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
180
+ define_method(synchronized_getter) { val }
181
+ end
166
182
  end
167
183
 
168
184
  if singleton_class?
data/lib/sidekiq.rb CHANGED
@@ -1,7 +1,7 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
2
+
3
3
  require 'sidekiq/version'
4
- fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && RUBY_VERSION < '2.2.2'
4
+ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.2.2." if RUBY_PLATFORM != 'java' && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
5
5
 
6
6
  require 'sidekiq/logging'
7
7
  require 'sidekiq/client'
@@ -12,13 +12,13 @@ require 'sidekiq/delay'
12
12
  require 'json'
13
13
 
14
14
  module Sidekiq
15
- NAME = 'Sidekiq'.freeze
15
+ NAME = 'Sidekiq'
16
16
  LICENSE = 'See LICENSE and the LGPL-3.0 for licensing details.'
17
17
 
18
18
  DEFAULTS = {
19
19
  queues: [],
20
20
  labels: [],
21
- concurrency: 25,
21
+ concurrency: 10,
22
22
  require: '.',
23
23
  environment: nil,
24
24
  timeout: 8,
@@ -48,7 +48,7 @@ module Sidekiq
48
48
  "connected_clients" => "9999",
49
49
  "used_memory_human" => "9P",
50
50
  "used_memory_peak_human" => "9P"
51
- }.freeze
51
+ }
52
52
 
53
53
  def self.❨╯°□°❩╯︵┻━┻
54
54
  puts "Calm down, yo."
@@ -57,6 +57,7 @@ module Sidekiq
57
57
  def self.options
58
58
  @options ||= DEFAULTS.dup
59
59
  end
60
+
60
61
  def self.options=(opts)
61
62
  @options = opts
62
63
  end
@@ -95,8 +96,8 @@ module Sidekiq
95
96
  begin
96
97
  yield conn
97
98
  rescue Redis::CommandError => ex
98
- #2550 Failover can cause the server to become a slave, need
99
- # to disconnect and reopen the socket to get back to the master.
99
+ #2550 Failover can cause the server to become a replica, need
100
+ # to disconnect and reopen the socket to get back to the primary.
100
101
  (conn.disconnect!; retryable = false; retry) if retryable && ex.message =~ /READONLY/
101
102
  raise
102
103
  end
data/sidekiq.gemspec CHANGED
@@ -1,5 +1,4 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/sidekiq/version', __FILE__)
1
+ require_relative 'lib/sidekiq/version'
3
2
 
4
3
  Gem::Specification.new do |gem|
5
4
  gem.authors = ["Mike Perham"]
@@ -11,18 +10,12 @@ Gem::Specification.new do |gem|
11
10
 
12
11
  gem.executables = ['sidekiq', 'sidekiqctl']
13
12
  gem.files = `git ls-files | grep -Ev '^(test|myapp|examples)'`.split("\n")
14
- gem.test_files = []
15
13
  gem.name = "sidekiq"
16
- gem.require_paths = ["lib"]
17
14
  gem.version = Sidekiq::VERSION
18
15
  gem.required_ruby_version = ">= 2.2.2"
19
16
 
20
- gem.add_dependency 'redis', '>= 3.3.5', '< 5'
21
- gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.0'
22
- gem.add_dependency 'concurrent-ruby', '~> 1.0'
23
- gem.add_dependency 'rack-protection', '>= 1.5.0'
24
- gem.add_development_dependency 'redis-namespace', '~> 1.5', '>= 1.5.2'
25
- gem.add_development_dependency 'minitest', '~> 5.10', '>= 5.10.1'
26
- gem.add_development_dependency 'rake', '~> 10.0'
27
- gem.add_development_dependency 'rails', '>= 3.2.0'
17
+ gem.add_dependency "redis", "~> 4.5", "< 4.6.0"
18
+ gem.add_dependency 'connection_pool', '~> 2.2', '>= 2.2.2'
19
+ gem.add_dependency 'rack', '~> 2.0'
20
+ gem.add_dependency 'rack-protection', '>= 1.5.0'
28
21
  end
File without changes
@@ -298,8 +298,18 @@ var debounce = function(fn, timeout)
298
298
  }
299
299
  };
300
300
 
301
- window.onresize = debounce(function() {
302
- clearInterval(poller);
303
- resetGraphs();
304
- renderGraphs();
305
- }, 125);
301
+ window.onresize = function() {
302
+ var prevWidth = window.innerWidth;
303
+
304
+ return debounce(function () {
305
+ var currWidth = window.innerWidth;
306
+
307
+ if (prevWidth !== currWidth) {
308
+ prevWidth = currWidth;
309
+
310
+ clearInterval(poller);
311
+ resetGraphs();
312
+ renderGraphs();
313
+ }
314
+ }, 125);
315
+ }();
@@ -126,7 +126,7 @@ header.row .pagination {
126
126
  text-align: center;
127
127
  width: 14%;
128
128
  }
129
- @media (max-width: 767px) and (min-width: 400px) {
129
+ @media (max-width: 767px) and (min-width: 200px) {
130
130
  .summary_bar ul li {
131
131
  width: 100%;
132
132
  }
@@ -219,6 +219,29 @@ table .table-checkbox label {
219
219
  color: #585454;
220
220
  }
221
221
 
222
+
223
+ .nav.navbar-nav{
224
+ display: flex;
225
+ width: 100%;
226
+ }
227
+
228
+ .navbar-livereload{
229
+ margin-left: auto;
230
+ white-space: nowrap;
231
+ }
232
+
233
+ .navbar-livereload .poll-wrapper a:last-child{
234
+ margin-left: 8px;
235
+ }
236
+
237
+ .navbar-right{
238
+ margin-right: 0;
239
+ }
240
+
241
+ .navbar-collapse.collapse{
242
+ overflow-x: auto !important;
243
+ }
244
+
222
245
  @media (max-width: 768px) {
223
246
  .navbar .navbar-header .navbar-livereload {
224
247
  border: none;
@@ -234,13 +257,19 @@ table .table-checkbox label {
234
257
  display: none;
235
258
  }
236
259
 
260
+ .nav.navbar-nav{
261
+ display: block;
262
+ width: auto;
263
+ }
264
+
237
265
  .navbar.navbar-fixed-top ul {
238
266
  margin-right: -15px!important;
239
267
  }
240
268
 
241
269
  .navbar .nav a {
242
270
  text-align: center;
243
- }
271
+ }
272
+
244
273
  }
245
274
 
246
275
  @media (width: 768px) {
@@ -645,6 +674,10 @@ div.interval-slider input {
645
674
  margin-right: 0;
646
675
  }
647
676
 
677
+ .navbar #navbar-menu{
678
+ display: none;
679
+ }
680
+
648
681
  .poll-wrapper {
649
682
  width: 100%;
650
683
  text-align: center;