sidekiq 6.4.2 → 6.5.2

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +35 -0
  3. data/bin/sidekiqload +15 -3
  4. data/lib/sidekiq/api.rb +160 -32
  5. data/lib/sidekiq/cli.rb +34 -32
  6. data/lib/sidekiq/client.rb +4 -4
  7. data/lib/sidekiq/component.rb +65 -0
  8. data/lib/sidekiq/delay.rb +1 -1
  9. data/lib/sidekiq/fetch.rb +16 -14
  10. data/lib/sidekiq/job_retry.rb +50 -34
  11. data/lib/sidekiq/job_util.rb +7 -3
  12. data/lib/sidekiq/launcher.rb +22 -19
  13. data/lib/sidekiq/logger.rb +1 -1
  14. data/lib/sidekiq/manager.rb +23 -20
  15. data/lib/sidekiq/metrics/deploy.rb +47 -0
  16. data/lib/sidekiq/metrics/query.rb +124 -0
  17. data/lib/sidekiq/metrics/shared.rb +94 -0
  18. data/lib/sidekiq/metrics/tracking.rb +134 -0
  19. data/lib/sidekiq/middleware/chain.rb +82 -38
  20. data/lib/sidekiq/middleware/current_attributes.rb +10 -4
  21. data/lib/sidekiq/middleware/i18n.rb +2 -0
  22. data/lib/sidekiq/middleware/modules.rb +21 -0
  23. data/lib/sidekiq/paginator.rb +2 -2
  24. data/lib/sidekiq/processor.rb +13 -13
  25. data/lib/sidekiq/rails.rb +5 -5
  26. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  27. data/lib/sidekiq/redis_connection.rb +80 -47
  28. data/lib/sidekiq/ring_buffer.rb +29 -0
  29. data/lib/sidekiq/scheduled.rb +11 -10
  30. data/lib/sidekiq/testing.rb +1 -1
  31. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  32. data/lib/sidekiq/version.rb +1 -1
  33. data/lib/sidekiq/web/application.rb +13 -0
  34. data/lib/sidekiq/web/helpers.rb +25 -2
  35. data/lib/sidekiq/web.rb +4 -0
  36. data/lib/sidekiq/worker.rb +2 -1
  37. data/lib/sidekiq.rb +87 -18
  38. data/sidekiq.gemspec +1 -1
  39. data/web/assets/javascripts/application.js +1 -1
  40. data/web/assets/javascripts/dashboard.js +0 -17
  41. data/web/assets/javascripts/graph.js +16 -0
  42. data/web/locales/en.yml +4 -0
  43. data/web/locales/pt-br.yml +27 -9
  44. data/web/views/_nav.erb +1 -1
  45. data/web/views/busy.erb +1 -1
  46. data/web/views/dashboard.erb +1 -0
  47. data/web/views/metrics.erb +59 -0
  48. data/web/views/metrics_for_job.erb +92 -0
  49. data/web/views/queue.erb +5 -1
  50. metadata +16 -6
  51. data/lib/sidekiq/exception_handler.rb +0 -27
  52. data/lib/sidekiq/util.rb +0 -108
@@ -5,8 +5,81 @@ require "redis"
5
5
  require "uri"
6
6
 
7
7
  module Sidekiq
8
- class RedisConnection
8
+ module RedisConnection
9
+ class RedisAdapter
10
+ BaseError = Redis::BaseError
11
+ CommandError = Redis::CommandError
12
+
13
+ def initialize(options)
14
+ warn("Usage of the 'redis' gem within Sidekiq itself is deprecated, Sidekiq 7.0 will only use the new, simpler 'redis-client' gem", caller) if ENV["SIDEKIQ_REDIS_CLIENT"] == "1"
15
+ @options = options
16
+ end
17
+
18
+ def new_client
19
+ namespace = @options[:namespace]
20
+
21
+ client = Redis.new client_opts(@options)
22
+ if namespace
23
+ begin
24
+ require "redis/namespace"
25
+ Redis::Namespace.new(namespace, redis: client)
26
+ rescue LoadError
27
+ Sidekiq.logger.error("Your Redis configuration uses the namespace '#{namespace}' but the redis-namespace gem is not included in the Gemfile." \
28
+ "Add the gem to your Gemfile to continue using a namespace. Otherwise, remove the namespace parameter.")
29
+ exit(-127)
30
+ end
31
+ else
32
+ client
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def client_opts(options)
39
+ opts = options.dup
40
+ if opts[:namespace]
41
+ opts.delete(:namespace)
42
+ end
43
+
44
+ if opts[:network_timeout]
45
+ opts[:timeout] = opts[:network_timeout]
46
+ opts.delete(:network_timeout)
47
+ end
48
+
49
+ opts[:driver] ||= Redis::Connection.drivers.last || "ruby"
50
+
51
+ # Issue #3303, redis-rb will silently retry an operation.
52
+ # This can lead to duplicate jobs if Sidekiq::Client's LPUSH
53
+ # is performed twice but I believe this is much, much rarer
54
+ # than the reconnect silently fixing a problem; we keep it
55
+ # on by default.
56
+ opts[:reconnect_attempts] ||= 1
57
+
58
+ opts
59
+ end
60
+ end
61
+
62
+ @adapter = RedisAdapter
63
+
9
64
  class << self
65
+ attr_reader :adapter
66
+
67
+ # RedisConnection.adapter = :redis
68
+ # RedisConnection.adapter = :redis_client
69
+ def adapter=(adapter)
70
+ raise "no" if adapter == self
71
+ result = case adapter
72
+ when :redis
73
+ RedisAdapter
74
+ when Class
75
+ adapter
76
+ else
77
+ require "sidekiq/#{adapter}_adapter"
78
+ nil
79
+ end
80
+ @adapter = result if result
81
+ end
82
+
10
83
  def create(options = {})
11
84
  symbolized_options = options.transform_keys(&:to_sym)
12
85
 
@@ -19,20 +92,21 @@ module Sidekiq
19
92
  elsif Sidekiq.server?
20
93
  # Give ourselves plenty of connections. pool is lazy
21
94
  # so we won't create them until we need them.
22
- Sidekiq.options[:concurrency] + 5
95
+ Sidekiq[:concurrency] + 5
23
96
  elsif ENV["RAILS_MAX_THREADS"]
24
97
  Integer(ENV["RAILS_MAX_THREADS"])
25
98
  else
26
99
  5
27
100
  end
28
101
 
29
- verify_sizing(size, Sidekiq.options[:concurrency]) if Sidekiq.server?
102
+ verify_sizing(size, Sidekiq[:concurrency]) if Sidekiq.server?
30
103
 
31
104
  pool_timeout = symbolized_options[:pool_timeout] || 1
32
105
  log_info(symbolized_options)
33
106
 
107
+ redis_config = adapter.new(symbolized_options)
34
108
  ConnectionPool.new(timeout: pool_timeout, size: size) do
35
- build_client(symbolized_options)
109
+ redis_config.new_client
36
110
  end
37
111
  end
38
112
 
@@ -50,47 +124,6 @@ module Sidekiq
50
124
  raise ArgumentError, "Your Redis connection pool is too small for Sidekiq. Your pool has #{size} connections but must have at least #{concurrency + 2}" if size < (concurrency + 2)
51
125
  end
52
126
 
53
- def build_client(options)
54
- namespace = options[:namespace]
55
-
56
- client = Redis.new client_opts(options)
57
- if namespace
58
- begin
59
- require "redis/namespace"
60
- Redis::Namespace.new(namespace, redis: client)
61
- rescue LoadError
62
- Sidekiq.logger.error("Your Redis configuration uses the namespace '#{namespace}' but the redis-namespace gem is not included in the Gemfile." \
63
- "Add the gem to your Gemfile to continue using a namespace. Otherwise, remove the namespace parameter.")
64
- exit(-127)
65
- end
66
- else
67
- client
68
- end
69
- end
70
-
71
- def client_opts(options)
72
- opts = options.dup
73
- if opts[:namespace]
74
- opts.delete(:namespace)
75
- end
76
-
77
- if opts[:network_timeout]
78
- opts[:timeout] = opts[:network_timeout]
79
- opts.delete(:network_timeout)
80
- end
81
-
82
- opts[:driver] ||= Redis::Connection.drivers.last || "ruby"
83
-
84
- # Issue #3303, redis-rb will silently retry an operation.
85
- # This can lead to duplicate jobs if Sidekiq::Client's LPUSH
86
- # is performed twice but I believe this is much, much rarer
87
- # than the reconnect silently fixing a problem; we keep it
88
- # on by default.
89
- opts[:reconnect_attempts] ||= 1
90
-
91
- opts
92
- end
93
-
94
127
  def log_info(options)
95
128
  redacted = "REDACTED"
96
129
 
@@ -110,9 +143,9 @@ module Sidekiq
110
143
  sentinel[:password] = redacted if sentinel[:password]
111
144
  end
112
145
  if Sidekiq.server?
113
- Sidekiq.logger.info("Booting Sidekiq #{Sidekiq::VERSION} with redis options #{scrubbed_options}")
146
+ Sidekiq.logger.info("Booting Sidekiq #{Sidekiq::VERSION} with #{adapter.name} options #{scrubbed_options}")
114
147
  else
115
- Sidekiq.logger.debug("#{Sidekiq::NAME} client with redis options #{scrubbed_options}")
148
+ Sidekiq.logger.debug("#{Sidekiq::NAME} client with #{adapter.name} options #{scrubbed_options}")
116
149
  end
117
150
  end
118
151
 
@@ -0,0 +1,29 @@
1
+ require "forwardable"
2
+
3
+ module Sidekiq
4
+ class RingBuffer
5
+ include Enumerable
6
+ extend Forwardable
7
+ def_delegators :@buf, :[], :each, :size
8
+
9
+ def initialize(size, default = 0)
10
+ @size = size
11
+ @buf = Array.new(size, default)
12
+ @index = 0
13
+ end
14
+
15
+ def <<(element)
16
+ @buf[@index % @size] = element
17
+ @index += 1
18
+ element
19
+ end
20
+
21
+ def buffer
22
+ @buf
23
+ end
24
+
25
+ def reset(default = 0)
26
+ @buf.fill(default)
27
+ end
28
+ end
29
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "sidekiq"
4
- require "sidekiq/util"
5
4
  require "sidekiq/api"
5
+ require "sidekiq/component"
6
6
 
7
7
  module Sidekiq
8
8
  module Scheduled
@@ -52,8 +52,8 @@ module Sidekiq
52
52
  @lua_zpopbyscore_sha = raw_conn.script(:load, LUA_ZPOPBYSCORE)
53
53
  end
54
54
 
55
- conn.evalsha(@lua_zpopbyscore_sha, keys: keys, argv: argv)
56
- rescue Redis::CommandError => e
55
+ conn.evalsha(@lua_zpopbyscore_sha, keys, argv)
56
+ rescue RedisConnection.adapter::CommandError => e
57
57
  raise unless e.message.start_with?("NOSCRIPT")
58
58
 
59
59
  @lua_zpopbyscore_sha = nil
@@ -67,12 +67,13 @@ module Sidekiq
67
67
  # just pops the job back onto its original queue so the
68
68
  # workers can pick it up like any other job.
69
69
  class Poller
70
- include Util
70
+ include Sidekiq::Component
71
71
 
72
72
  INITIAL_WAIT = 10
73
73
 
74
- def initialize
75
- @enq = (Sidekiq.options[:scheduled_enq] || Sidekiq::Scheduled::Enq).new
74
+ def initialize(options)
75
+ @config = options
76
+ @enq = (options[:scheduled_enq] || Sidekiq::Scheduled::Enq).new
76
77
  @sleeper = ConnectionPool::TimedStack.new
77
78
  @done = false
78
79
  @thread = nil
@@ -100,7 +101,7 @@ module Sidekiq
100
101
  enqueue
101
102
  wait
102
103
  end
103
- Sidekiq.logger.info("Scheduler exiting...")
104
+ logger.info("Scheduler exiting...")
104
105
  }
105
106
  end
106
107
 
@@ -171,14 +172,14 @@ module Sidekiq
171
172
  #
172
173
  # We only do this if poll_interval_average is unset (the default).
173
174
  def poll_interval_average
174
- Sidekiq.options[:poll_interval_average] ||= scaled_poll_interval
175
+ @config[:poll_interval_average] ||= scaled_poll_interval
175
176
  end
176
177
 
177
178
  # Calculates an average poll interval based on the number of known Sidekiq processes.
178
179
  # This minimizes a single point of failure by dispersing check-ins but without taxing
179
180
  # Redis if you run many Sidekiq processes.
180
181
  def scaled_poll_interval
181
- process_count * Sidekiq.options[:average_scheduled_poll_interval]
182
+ process_count * @config[:average_scheduled_poll_interval]
182
183
  end
183
184
 
184
185
  def process_count
@@ -197,7 +198,7 @@ module Sidekiq
197
198
  # to give time for the heartbeat to register (if the poll interval is going to be calculated by the number
198
199
  # of workers), and 5 random seconds to ensure they don't all hit Redis at the same time.
199
200
  total = 0
200
- total += INITIAL_WAIT unless Sidekiq.options[:poll_interval_average]
201
+ total += INITIAL_WAIT unless @config[:poll_interval_average]
201
202
  total += (5 * rand)
202
203
 
203
204
  @sleeper.pop(total)
@@ -188,7 +188,7 @@ module Sidekiq
188
188
  end
189
189
 
190
190
  def clear_for(queue, klass)
191
- jobs_by_queue[queue].clear
191
+ jobs_by_queue[queue.to_s].clear
192
192
  jobs_by_class[klass].clear
193
193
  end
194
194
 
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "securerandom"
4
+ require "sidekiq/client"
5
+
6
+ module Sidekiq
7
+ class TransactionAwareClient
8
+ def initialize(redis_pool)
9
+ @redis_client = Client.new(redis_pool)
10
+ end
11
+
12
+ def push(item)
13
+ # pre-allocate the JID so we can return it immediately and
14
+ # save it to the database as part of the transaction.
15
+ item["jid"] ||= SecureRandom.hex(12)
16
+ AfterCommitEverywhere.after_commit { @redis_client.push(item) }
17
+ item["jid"]
18
+ end
19
+
20
+ ##
21
+ # We don't provide transactionality for push_bulk because we don't want
22
+ # to hold potentially hundreds of thousands of job records in memory due to
23
+ # a long running enqueue process.
24
+ def push_bulk(items)
25
+ @redis_client.push_bulk(items)
26
+ end
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Use `Sidekiq.transactional_push!` in your sidekiq.rb initializer
32
+ module Sidekiq
33
+ def self.transactional_push!
34
+ begin
35
+ require "after_commit_everywhere"
36
+ rescue LoadError
37
+ Sidekiq.logger.error("You need to add after_commit_everywhere to your Gemfile to use Sidekiq's transactional client")
38
+ raise
39
+ end
40
+
41
+ default_job_options["client_class"] = Sidekiq::TransactionAwareClient
42
+ Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
43
+ true
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "6.4.2"
4
+ VERSION = "6.5.2"
5
5
  end
@@ -60,6 +60,19 @@ module Sidekiq
60
60
  erb(:dashboard)
61
61
  end
62
62
 
63
+ get "/metrics" do
64
+ q = Sidekiq::Metrics::Query.new
65
+ @resultset = q.top_jobs
66
+ erb(:metrics)
67
+ end
68
+
69
+ get "/metrics/:name" do
70
+ @name = route_params[:name]
71
+ q = Sidekiq::Metrics::Query.new
72
+ @resultset = q.for_job(@name)
73
+ erb(:metrics_for_job)
74
+ end
75
+
63
76
  get "/busy" do
64
77
  erb(:busy)
65
78
  end
@@ -15,7 +15,7 @@ module Sidekiq
15
15
  # so extensions can be localized
16
16
  @strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
17
17
  find_locale_files(lang).each do |file|
18
- strs = YAML.load(File.open(file))
18
+ strs = YAML.safe_load(File.open(file))
19
19
  global.merge!(strs[lang])
20
20
  end
21
21
  end
@@ -148,6 +148,29 @@ module Sidekiq
148
148
  @processes ||= Sidekiq::ProcessSet.new
149
149
  end
150
150
 
151
+ # Sorts processes by hostname following the natural sort order so that
152
+ # 'worker.1' < 'worker.2' < 'worker.10' < 'worker.20'
153
+ # '2.1.1.1' < '192.168.0.2' < '192.168.0.10'
154
+ def sorted_processes
155
+ @sorted_processes ||= begin
156
+ return processes unless processes.all? { |p| p["hostname"] }
157
+
158
+ split_characters = /[._-]/
159
+
160
+ padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
161
+
162
+ processes.to_a.sort_by do |process|
163
+ process["hostname"].split(split_characters).map do |substring|
164
+ # Left-pad the substring with '0' if it starts with a number or 'a'
165
+ # otherwise, so that '25' < 192' < 'a' ('025' < '192' < 'aaa')
166
+ padding_char = substring[0].match?(/\d/) ? "0" : "a"
167
+
168
+ substring.rjust(padding, padding_char)
169
+ end
170
+ end
171
+ end
172
+ end
173
+
151
174
  def stats
152
175
  @stats ||= Sidekiq::Stats.new
153
176
  end
@@ -301,7 +324,7 @@ module Sidekiq
301
324
  end
302
325
 
303
326
  def environment_title_prefix
304
- environment = Sidekiq.options[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
327
+ environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
305
328
 
306
329
  "[#{environment.upcase}] " unless environment == "production"
307
330
  end
data/lib/sidekiq/web.rb CHANGED
@@ -33,6 +33,10 @@ module Sidekiq
33
33
  "Dead" => "morgue"
34
34
  }
35
35
 
36
+ if ENV["SIDEKIQ_METRICS_BETA"] == "1"
37
+ DEFAULT_TABS["Metrics"] = "metrics"
38
+ end
39
+
36
40
  class << self
37
41
  def settings
38
42
  self
@@ -359,7 +359,8 @@ module Sidekiq
359
359
 
360
360
  def build_client # :nodoc:
361
361
  pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
362
- Sidekiq::Client.new(pool)
362
+ client_class = get_sidekiq_options["client_class"] || Sidekiq::Client
363
+ client_class.new(pool)
363
364
  end
364
365
  end
365
366
  end
data/lib/sidekiq.rb CHANGED
@@ -5,6 +5,7 @@ fail "Sidekiq #{Sidekiq::VERSION} does not support Ruby versions below 2.5.0." i
5
5
 
6
6
  require "sidekiq/logger"
7
7
  require "sidekiq/client"
8
+ require "sidekiq/transaction_aware_client"
8
9
  require "sidekiq/worker"
9
10
  require "sidekiq/job"
10
11
  require "sidekiq/redis_connection"
@@ -33,7 +34,10 @@ module Sidekiq
33
34
  startup: [],
34
35
  quiet: [],
35
36
  shutdown: [],
36
- heartbeat: []
37
+ # triggers when we fire the first heartbeat on startup OR repairing a network partition
38
+ heartbeat: [],
39
+ # triggers on EVERY heartbeat call, every 10 seconds
40
+ beat: []
37
41
  },
38
42
  dead_max_jobs: 10_000,
39
43
  dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
@@ -52,19 +56,84 @@ module Sidekiq
52
56
  puts "Calm down, yo."
53
57
  end
54
58
 
59
+ # config.concurrency = 5
60
+ def self.concurrency=(val)
61
+ self[:concurrency] = Integer(val)
62
+ end
63
+
64
+ # config.queues = %w( high default low ) # strict
65
+ # config.queues = %w( high,3 default,2 low,1 ) # weighted
66
+ # config.queues = %w( feature1,1 feature2,1 feature3,1 ) # random
67
+ #
68
+ # With weighted priority, queue will be checked first (weight / total) of the time.
69
+ # high will be checked first (3/6) or 50% of the time.
70
+ # I'd recommend setting weights between 1-10. Weights in the hundreds or thousands
71
+ # are ridiculous and unnecessarily expensive. You can get random queue ordering
72
+ # by explicitly setting all weights to 1.
73
+ def self.queues=(val)
74
+ self[:queues] = Array(val).each_with_object([]) do |qstr, memo|
75
+ name, weight = qstr.split(",")
76
+ self[:strict] = false if weight.to_i > 0
77
+ [weight.to_i, 1].max.times do
78
+ memo << name
79
+ end
80
+ end
81
+ end
82
+
83
+ ### Private APIs
84
+ def self.default_error_handler(ex, ctx)
85
+ logger.warn(dump_json(ctx)) unless ctx.empty?
86
+ logger.warn("#{ex.class.name}: #{ex.message}")
87
+ logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
88
+ end
89
+
90
+ # DEFAULT_ERROR_HANDLER is a constant that allows the default error handler to
91
+ # be referenced. It must be defined here, after the default_error_handler
92
+ # method is defined.
93
+ DEFAULT_ERROR_HANDLER = method(:default_error_handler)
94
+
95
+ @config = DEFAULTS.dup
55
96
  def self.options
56
- @options ||= DEFAULTS.dup
97
+ logger.warn "`config.options[:key] = value` is deprecated, use `config[:key] = value`: #{caller(1..2)}"
98
+ @config
57
99
  end
58
100
 
59
101
  def self.options=(opts)
60
- @options = opts
102
+ logger.warn "config.options = hash` is deprecated, use `config.merge!(hash)`: #{caller(1..2)}"
103
+ @config = opts
104
+ end
105
+
106
+ def self.[](key)
107
+ @config[key]
108
+ end
109
+
110
+ def self.[]=(key, val)
111
+ @config[key] = val
112
+ end
113
+
114
+ def self.merge!(hash)
115
+ @config.merge!(hash)
116
+ end
117
+
118
+ def self.fetch(*args, &block)
119
+ @config.fetch(*args, &block)
120
+ end
121
+
122
+ def self.handle_exception(ex, ctx = {})
123
+ self[:error_handlers].each do |handler|
124
+ handler.call(ex, ctx)
125
+ rescue => ex
126
+ logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
127
+ logger.error ex
128
+ logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
129
+ end
61
130
  end
131
+ ###
62
132
 
63
133
  ##
64
134
  # Configuration for Sidekiq server, use like:
65
135
  #
66
136
  # Sidekiq.configure_server do |config|
67
- # config.redis = { :namespace => 'myapp', :size => 25, :url => 'redis://myhost:8877/0' }
68
137
  # config.server_middleware do |chain|
69
138
  # chain.add MyServerHook
70
139
  # end
@@ -77,7 +146,7 @@ module Sidekiq
77
146
  # Configuration for Sidekiq client, use like:
78
147
  #
79
148
  # Sidekiq.configure_client do |config|
80
- # config.redis = { :namespace => 'myapp', :size => 1, :url => 'redis://myhost:8877/0' }
149
+ # config.redis = { size: 1, url: 'redis://myhost:8877/0' }
81
150
  # end
82
151
  def self.configure_client
83
152
  yield self unless server?
@@ -93,7 +162,7 @@ module Sidekiq
93
162
  retryable = true
94
163
  begin
95
164
  yield conn
96
- rescue Redis::BaseError => ex
165
+ rescue RedisConnection.adapter::BaseError => ex
97
166
  # 2550 Failover can cause the server to become a replica, need
98
167
  # to disconnect and reopen the socket to get back to the primary.
99
168
  # 4495 Use the same logic if we have a "Not enough replicas" error from the primary
@@ -118,7 +187,7 @@ module Sidekiq
118
187
  else
119
188
  conn.info
120
189
  end
121
- rescue Redis::CommandError => ex
190
+ rescue RedisConnection.adapter::CommandError => ex
122
191
  # 2850 return fake version when INFO command has (probably) been renamed
123
192
  raise unless /unknown command/.match?(ex.message)
124
193
  FAKE_INFO
@@ -126,19 +195,19 @@ module Sidekiq
126
195
  end
127
196
 
128
197
  def self.redis_pool
129
- @redis ||= Sidekiq::RedisConnection.create
198
+ @redis ||= RedisConnection.create
130
199
  end
131
200
 
132
201
  def self.redis=(hash)
133
202
  @redis = if hash.is_a?(ConnectionPool)
134
203
  hash
135
204
  else
136
- Sidekiq::RedisConnection.create(hash)
205
+ RedisConnection.create(hash)
137
206
  end
138
207
  end
139
208
 
140
209
  def self.client_middleware
141
- @client_chain ||= Middleware::Chain.new
210
+ @client_chain ||= Middleware::Chain.new(self)
142
211
  yield @client_chain if block_given?
143
212
  @client_chain
144
213
  end
@@ -150,7 +219,7 @@ module Sidekiq
150
219
  end
151
220
 
152
221
  def self.default_server_middleware
153
- Middleware::Chain.new
222
+ Middleware::Chain.new(self)
154
223
  end
155
224
 
156
225
  def self.default_worker_options=(hash) # deprecated
@@ -179,7 +248,7 @@ module Sidekiq
179
248
  # end
180
249
  # end
181
250
  def self.death_handlers
182
- options[:death_handlers]
251
+ self[:death_handlers]
183
252
  end
184
253
 
185
254
  def self.load_json(string)
@@ -209,7 +278,7 @@ module Sidekiq
209
278
 
210
279
  def self.logger=(logger)
211
280
  if logger.nil?
212
- self.logger.fatal!
281
+ self.logger.level = Logger::FATAL
213
282
  return self.logger
214
283
  end
215
284
 
@@ -232,7 +301,7 @@ module Sidekiq
232
301
  #
233
302
  # See sidekiq/scheduled.rb for an in-depth explanation of this value
234
303
  def self.average_scheduled_poll_interval=(interval)
235
- options[:average_scheduled_poll_interval] = interval
304
+ self[:average_scheduled_poll_interval] = interval
236
305
  end
237
306
 
238
307
  # Register a proc to handle any error which occurs within the Sidekiq process.
@@ -243,7 +312,7 @@ module Sidekiq
243
312
  #
244
313
  # The default error handler logs errors to Sidekiq.logger.
245
314
  def self.error_handlers
246
- options[:error_handlers]
315
+ self[:error_handlers]
247
316
  end
248
317
 
249
318
  # Register a block to run at a point in the Sidekiq lifecycle.
@@ -256,12 +325,12 @@ module Sidekiq
256
325
  # end
257
326
  def self.on(event, &block)
258
327
  raise ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
259
- raise ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
260
- options[:lifecycle_events][event] << block
328
+ raise ArgumentError, "Invalid event name: #{event}" unless self[:lifecycle_events].key?(event)
329
+ self[:lifecycle_events][event] << block
261
330
  end
262
331
 
263
332
  def self.strict_args!(mode = :raise)
264
- options[:on_complex_arguments] = mode
333
+ self[:on_complex_arguments] = mode
265
334
  end
266
335
 
267
336
  # We are shutting down Sidekiq but what about threads that
data/sidekiq.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
22
22
  "source_code_uri" => "https://github.com/mperham/sidekiq"
23
23
  }
24
24
 
25
- gem.add_dependency "redis", ">= 4.2.0"
25
+ gem.add_dependency "redis", ">= 4.5.0"
26
26
  gem.add_dependency "connection_pool", ">= 2.2.2"
27
27
  gem.add_dependency "rack", "~> 2.0"
28
28
  end
@@ -63,7 +63,7 @@ function addPollingListeners(_event) {
63
63
  function addDataToggleListeners(event) {
64
64
  var source = event.target || event.srcElement;
65
65
  var targName = source.getAttribute("data-toggle");
66
- var full = document.getElementById(targName + "_full");
66
+ var full = document.getElementById(targName);
67
67
  if (full.style.display == "block") {
68
68
  full.style.display = 'none';
69
69
  } else {