sidekiq 6.5.6 → 7.0.0.beta1

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 (89) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +16 -4
  3. data/{LICENSE → LICENSE.txt} +0 -0
  4. data/README.md +13 -12
  5. data/bin/sidekiq +3 -8
  6. data/bin/sidekiqload +15 -24
  7. data/lib/sidekiq/api.rb +55 -111
  8. data/lib/sidekiq/capsule.rb +110 -0
  9. data/lib/sidekiq/cli.rb +44 -47
  10. data/lib/sidekiq/client.rb +29 -16
  11. data/lib/sidekiq/component.rb +1 -0
  12. data/lib/sidekiq/config.rb +270 -0
  13. data/lib/sidekiq/deploy.rb +62 -0
  14. data/lib/sidekiq/embedded.rb +61 -0
  15. data/lib/sidekiq/fetch.rb +10 -11
  16. data/lib/sidekiq/job.rb +375 -10
  17. data/lib/sidekiq/job_logger.rb +1 -1
  18. data/lib/sidekiq/job_retry.rb +8 -8
  19. data/lib/sidekiq/job_util.rb +4 -4
  20. data/lib/sidekiq/launcher.rb +36 -46
  21. data/lib/sidekiq/logger.rb +1 -26
  22. data/lib/sidekiq/manager.rb +9 -11
  23. data/lib/sidekiq/metrics/query.rb +2 -2
  24. data/lib/sidekiq/metrics/shared.rb +4 -3
  25. data/lib/sidekiq/metrics/tracking.rb +18 -18
  26. data/lib/sidekiq/middleware/chain.rb +7 -9
  27. data/lib/sidekiq/middleware/current_attributes.rb +8 -13
  28. data/lib/sidekiq/pool.rb +7 -0
  29. data/lib/sidekiq/processor.rb +17 -26
  30. data/lib/sidekiq/redis_client_adapter.rb +9 -45
  31. data/lib/sidekiq/redis_connection.rb +11 -111
  32. data/lib/sidekiq/scheduled.rb +58 -25
  33. data/lib/sidekiq/testing.rb +4 -32
  34. data/lib/sidekiq/transaction_aware_client.rb +4 -5
  35. data/lib/sidekiq/version.rb +1 -1
  36. data/lib/sidekiq/web/application.rb +1 -1
  37. data/lib/sidekiq/web/csrf_protection.rb +1 -1
  38. data/lib/sidekiq/web/helpers.rb +5 -16
  39. data/lib/sidekiq/web.rb +2 -17
  40. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  41. data/lib/sidekiq.rb +52 -274
  42. data/sidekiq.gemspec +29 -5
  43. data/web/assets/javascripts/base-charts.js +106 -0
  44. data/web/assets/javascripts/dashboard-charts.js +166 -0
  45. data/web/assets/javascripts/dashboard.js +3 -223
  46. data/web/assets/javascripts/metrics.js +90 -116
  47. data/web/assets/stylesheets/application-rtl.css +2 -91
  48. data/web/assets/stylesheets/application.css +21 -296
  49. data/web/locales/ar.yml +70 -70
  50. data/web/locales/cs.yml +62 -62
  51. data/web/locales/da.yml +52 -52
  52. data/web/locales/de.yml +65 -65
  53. data/web/locales/el.yml +2 -7
  54. data/web/locales/en.yml +76 -70
  55. data/web/locales/es.yml +68 -68
  56. data/web/locales/fa.yml +65 -65
  57. data/web/locales/fr.yml +67 -67
  58. data/web/locales/he.yml +65 -64
  59. data/web/locales/hi.yml +59 -59
  60. data/web/locales/it.yml +53 -53
  61. data/web/locales/ja.yml +71 -68
  62. data/web/locales/ko.yml +52 -52
  63. data/web/locales/lt.yml +66 -66
  64. data/web/locales/nb.yml +61 -61
  65. data/web/locales/nl.yml +52 -52
  66. data/web/locales/pl.yml +45 -45
  67. data/web/locales/pt-br.yml +59 -69
  68. data/web/locales/pt.yml +51 -51
  69. data/web/locales/ru.yml +67 -66
  70. data/web/locales/sv.yml +53 -53
  71. data/web/locales/ta.yml +60 -60
  72. data/web/locales/uk.yml +62 -61
  73. data/web/locales/ur.yml +64 -64
  74. data/web/locales/vi.yml +67 -67
  75. data/web/locales/zh-cn.yml +37 -11
  76. data/web/locales/zh-tw.yml +42 -8
  77. data/web/views/_footer.erb +5 -2
  78. data/web/views/dashboard.erb +36 -5
  79. data/web/views/metrics.erb +30 -19
  80. data/web/views/metrics_for_job.erb +16 -34
  81. metadata +59 -30
  82. data/lib/sidekiq/delay.rb +0 -43
  83. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  84. data/lib/sidekiq/extensions/active_record.rb +0 -43
  85. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  86. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  87. data/lib/sidekiq/metrics/deploy.rb +0 -47
  88. data/lib/sidekiq/worker.rb +0 -367
  89. data/web/assets/javascripts/graph.js +0 -16
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "connection_pool"
4
3
  require "redis_client"
5
4
  require "redis_client/decorator"
6
- require "uri"
7
5
 
8
6
  module Sidekiq
9
7
  class RedisClientAdapter
@@ -19,29 +17,10 @@ module Sidekiq
19
17
  @client.call("EVALSHA", sha, keys.size, *keys, *argv)
20
18
  end
21
19
 
22
- def brpoplpush(*args)
23
- @client.blocking_call(false, "BRPOPLPUSH", *args)
24
- end
25
-
26
- def brpop(*args)
27
- @client.blocking_call(false, "BRPOP", *args)
28
- end
29
-
30
- def set(*args)
31
- @client.call("SET", *args) { |r| r == "OK" }
32
- end
33
- ruby2_keywords :set if respond_to?(:ruby2_keywords, true)
34
-
35
- def sismember(*args)
36
- @client.call("SISMEMBER", *args) { |c| c > 0 }
37
- end
38
-
39
- def exists?(key)
40
- @client.call("EXISTS", key) { |c| c > 0 }
41
- end
42
-
43
20
  private
44
21
 
22
+ # this allows us to use methods like `conn.hmset(...)` instead of having to use
23
+ # redis-client's native `conn.call("hmset", ...)`
45
24
  def method_missing(*args, &block)
46
25
  @client.call(*args, *block)
47
26
  end
@@ -55,27 +34,15 @@ module Sidekiq
55
34
  CompatClient = RedisClient::Decorator.create(CompatMethods)
56
35
 
57
36
  class CompatClient
58
- %i[scan sscan zscan hscan].each do |method|
59
- alias_method :"#{method}_each", method
60
- undef_method method
61
- end
62
-
63
- def disconnect!
64
- @client.close
65
- end
66
-
67
- def connection
68
- {id: @client.id}
69
- end
70
-
71
- def redis
72
- self
73
- end
74
-
37
+ # underscore methods are not official API
75
38
  def _client
76
39
  @client
77
40
  end
78
41
 
42
+ def _config
43
+ @client.config
44
+ end
45
+
79
46
  def message
80
47
  yield nil, @queue.pop
81
48
  end
@@ -118,9 +85,8 @@ module Sidekiq
118
85
  opts = options.dup
119
86
 
120
87
  if opts[:namespace]
121
- Sidekiq.logger.error("Your Redis configuration uses the namespace '#{opts[:namespace]}' but this feature isn't supported by redis-client. " \
122
- "Either use the redis adapter or remove the namespace.")
123
- Kernel.exit(-127)
88
+ raise ArgumentError, "Your Redis configuration uses the namespace '#{opts[:namespace]}' but this feature isn't supported by redis-client. " \
89
+ "Either use the redis adapter or remove the namespace."
124
90
  end
125
91
 
126
92
  opts.delete(:size)
@@ -150,5 +116,3 @@ module Sidekiq
150
116
  end
151
117
  end
152
118
  end
153
-
154
- Sidekiq::RedisConnection.adapter = Sidekiq::RedisClientAdapter
@@ -1,128 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "connection_pool"
4
- require "redis"
5
4
  require "uri"
5
+ require "sidekiq/redis_client_adapter"
6
6
 
7
7
  module Sidekiq
8
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
- # Issue #3303, redis-rb will silently retry an operation.
50
- # This can lead to duplicate jobs if Sidekiq::Client's LPUSH
51
- # is performed twice but I believe this is much, much rarer
52
- # than the reconnect silently fixing a problem; we keep it
53
- # on by default.
54
- opts[:reconnect_attempts] ||= 1
55
-
56
- opts
57
- end
58
- end
59
-
60
- @adapter = RedisAdapter
61
-
62
9
  class << self
63
- attr_reader :adapter
64
-
65
- # RedisConnection.adapter = :redis
66
- # RedisConnection.adapter = :redis_client
67
- def adapter=(adapter)
68
- raise "no" if adapter == self
69
- result = case adapter
70
- when :redis
71
- RedisAdapter
72
- when Class
73
- adapter
74
- else
75
- require "sidekiq/#{adapter}_adapter"
76
- nil
77
- end
78
- @adapter = result if result
79
- end
80
-
81
10
  def create(options = {})
82
11
  symbolized_options = options.transform_keys(&:to_sym)
12
+ symbolized_options[:url] ||= determine_redis_provider
83
13
 
84
- if !symbolized_options[:url] && (u = determine_redis_provider)
85
- symbolized_options[:url] = u
86
- end
87
-
88
- size = if symbolized_options[:size]
89
- symbolized_options[:size]
90
- elsif Sidekiq.server?
91
- # Give ourselves plenty of connections. pool is lazy
92
- # so we won't create them until we need them.
93
- Sidekiq[:concurrency] + 5
94
- elsif ENV["RAILS_MAX_THREADS"]
95
- Integer(ENV["RAILS_MAX_THREADS"])
96
- else
97
- 5
98
- end
99
-
100
- verify_sizing(size, Sidekiq[:concurrency]) if Sidekiq.server?
14
+ logger = symbolized_options.delete(:logger)
15
+ logger&.info { "Sidekiq #{Sidekiq::VERSION} connecting to Redis with options #{scrub(symbolized_options)}" }
101
16
 
102
- pool_timeout = symbolized_options[:pool_timeout] || 1
103
- log_info(symbolized_options)
17
+ size = symbolized_options.delete(:size) || 5
18
+ pool_timeout = symbolized_options.delete(:pool_timeout) || 1
19
+ pool_name = symbolized_options.delete(:pool_name)
104
20
 
105
- redis_config = adapter.new(symbolized_options)
106
- ConnectionPool.new(timeout: pool_timeout, size: size) do
21
+ redis_config = Sidekiq::RedisClientAdapter.new(symbolized_options)
22
+ ConnectionPool.new(timeout: pool_timeout, size: size, name: pool_name) do
107
23
  redis_config.new_client
108
24
  end
109
25
  end
110
26
 
111
27
  private
112
28
 
113
- # Sidekiq needs many concurrent Redis connections.
114
- #
115
- # We need a connection for each Processor.
116
- # We need a connection for Pro's real-time change listener
117
- # We need a connection to various features to call Redis every few seconds:
118
- # - the process heartbeat.
119
- # - enterprise's leader election
120
- # - enterprise's cron support
121
- def verify_sizing(size, concurrency)
122
- 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)
123
- end
124
-
125
- def log_info(options)
29
+ def scrub(options)
126
30
  redacted = "REDACTED"
127
31
 
128
32
  # Deep clone so we can muck with these options all we want and exclude
@@ -140,11 +44,7 @@ module Sidekiq
140
44
  scrubbed_options[:sentinels]&.each do |sentinel|
141
45
  sentinel[:password] = redacted if sentinel[:password]
142
46
  end
143
- if Sidekiq.server?
144
- Sidekiq.logger.info("Booting Sidekiq #{Sidekiq::VERSION} with #{adapter.name} options #{scrubbed_options}")
145
- else
146
- Sidekiq.logger.debug("#{Sidekiq::NAME} client with #{adapter.name} options #{scrubbed_options}")
147
- end
47
+ scrubbed_options
148
48
  end
149
49
 
150
50
  def determine_redis_provider
@@ -8,6 +8,8 @@ module Sidekiq
8
8
  SETS = %w[retry schedule]
9
9
 
10
10
  class Enq
11
+ include Sidekiq::Component
12
+
11
13
  LUA_ZPOPBYSCORE = <<~LUA
12
14
  local key, now = KEYS[1], ARGV[1]
13
15
  local jobs = redis.call("zrangebyscore", key, "-inf", now, "limit", 0, 1)
@@ -17,7 +19,9 @@ module Sidekiq
17
19
  end
18
20
  LUA
19
21
 
20
- def initialize
22
+ def initialize(container)
23
+ @config = container
24
+ @client = Sidekiq::Client.new(config: container)
21
25
  @done = false
22
26
  @lua_zpopbyscore_sha = nil
23
27
  end
@@ -25,15 +29,15 @@ module Sidekiq
25
29
  def enqueue_jobs(sorted_sets = SETS)
26
30
  # A job's "score" in Redis is the time at which it should be processed.
27
31
  # Just check Redis for the set of jobs with a timestamp before now.
28
- Sidekiq.redis do |conn|
32
+ redis do |conn|
29
33
  sorted_sets.each do |sorted_set|
30
34
  # Get next item in the queue with score (time to execute) <= now.
31
35
  # We need to go through the list one at a time to reduce the risk of something
32
36
  # going wrong between the time jobs are popped from the scheduled queue and when
33
37
  # they are pushed onto a work queue and losing the jobs.
34
38
  while !@done && (job = zpopbyscore(conn, keys: [sorted_set], argv: [Time.now.to_f.to_s]))
35
- Sidekiq::Client.push(Sidekiq.load_json(job))
36
- Sidekiq.logger.debug { "enqueued #{sorted_set}: #{job}" }
39
+ @client.push(Sidekiq.load_json(job))
40
+ logger.debug { "enqueued #{sorted_set}: #{job}" }
37
41
  end
38
42
  end
39
43
  end
@@ -47,12 +51,11 @@ module Sidekiq
47
51
 
48
52
  def zpopbyscore(conn, keys: nil, argv: nil)
49
53
  if @lua_zpopbyscore_sha.nil?
50
- raw_conn = conn.respond_to?(:redis) ? conn.redis : conn
51
- @lua_zpopbyscore_sha = raw_conn.script(:load, LUA_ZPOPBYSCORE)
54
+ @lua_zpopbyscore_sha = conn.script(:load, LUA_ZPOPBYSCORE)
52
55
  end
53
56
 
54
57
  conn.evalsha(@lua_zpopbyscore_sha, keys, argv)
55
- rescue RedisConnection.adapter::CommandError => e
58
+ rescue RedisClient::CommandError => e
56
59
  raise unless e.message.start_with?("NOSCRIPT")
57
60
 
58
61
  @lua_zpopbyscore_sha = nil
@@ -70,9 +73,9 @@ module Sidekiq
70
73
 
71
74
  INITIAL_WAIT = 10
72
75
 
73
- def initialize(options)
74
- @config = options
75
- @enq = (options[:scheduled_enq] || Sidekiq::Scheduled::Enq).new
76
+ def initialize(config)
77
+ @config = config
78
+ @enq = (config[:scheduled_enq] || Sidekiq::Scheduled::Enq).new(config)
76
79
  @sleeper = ConnectionPool::TimedStack.new
77
80
  @done = false
78
81
  @thread = nil
@@ -82,14 +85,10 @@ module Sidekiq
82
85
  # Shut down this instance, will pause until the thread is dead.
83
86
  def terminate
84
87
  @done = true
85
- @enq.terminate if @enq.respond_to?(:terminate)
88
+ @enq.terminate
86
89
 
87
- if @thread
88
- t = @thread
89
- @thread = nil
90
- @sleeper << 0
91
- t.value
92
- end
90
+ @sleeper << 0
91
+ @thread&.value
93
92
  end
94
93
 
95
94
  def start
@@ -147,13 +146,16 @@ module Sidekiq
147
146
  # As we run more processes, the scheduling interval average will approach an even spread
148
147
  # between 0 and poll interval so we don't need this artifical boost.
149
148
  #
150
- if process_count < 10
149
+ count = process_count
150
+ interval = poll_interval_average(count)
151
+
152
+ if count < 10
151
153
  # For small clusters, calculate a random interval that is ±50% the desired average.
152
- poll_interval_average * rand + poll_interval_average.to_f / 2
154
+ interval * rand + interval.to_f / 2
153
155
  else
154
156
  # With 10+ processes, we should have enough randomness to get decent polling
155
157
  # across the entire timespan
156
- poll_interval_average * rand
158
+ interval * rand
157
159
  end
158
160
  end
159
161
 
@@ -170,14 +172,14 @@ module Sidekiq
170
172
  # the same time: the thundering herd problem.
171
173
  #
172
174
  # We only do this if poll_interval_average is unset (the default).
173
- def poll_interval_average
174
- @config[:poll_interval_average] ||= scaled_poll_interval
175
+ def poll_interval_average(count)
176
+ @config[:poll_interval_average] || scaled_poll_interval(count)
175
177
  end
176
178
 
177
179
  # Calculates an average poll interval based on the number of known Sidekiq processes.
178
180
  # This minimizes a single point of failure by dispersing check-ins but without taxing
179
181
  # Redis if you run many Sidekiq processes.
180
- def scaled_poll_interval
182
+ def scaled_poll_interval(process_count)
181
183
  process_count * @config[:average_scheduled_poll_interval]
182
184
  end
183
185
 
@@ -187,9 +189,35 @@ module Sidekiq
187
189
  pcount
188
190
  end
189
191
 
192
+ # A copy of Sidekiq::ProcessSet#cleanup because server
193
+ # should never depend on sidekiq/api.
194
+ def cleanup
195
+ # dont run cleanup more than once per minute
196
+ return 0 unless redis { |conn| conn.set("process_cleanup", "1", nx: true, ex: 60) }
197
+
198
+ count = 0
199
+ redis do |conn|
200
+ procs = conn.sscan("processes").to_a
201
+ heartbeats = conn.pipelined { |pipeline|
202
+ procs.each do |key|
203
+ pipeline.hget(key, "info")
204
+ end
205
+ }
206
+
207
+ # the hash named key has an expiry of 60 seconds.
208
+ # if it's not found, that means the process has not reported
209
+ # in to Redis and probably died.
210
+ to_prune = procs.select.with_index { |proc, i|
211
+ heartbeats[i].nil?
212
+ }
213
+ count = conn.srem("processes", to_prune) unless to_prune.empty?
214
+ end
215
+ count
216
+ end
217
+
190
218
  def initial_wait
191
- # Have all processes sleep between 5-15 seconds. 10 seconds
192
- # to give time for the heartbeat to register (if the poll interval is going to be calculated by the number
219
+ # Have all processes sleep between 5-15 seconds. 10 seconds to give time for
220
+ # the heartbeat to register (if the poll interval is going to be calculated by the number
193
221
  # of workers), and 5 random seconds to ensure they don't all hit Redis at the same time.
194
222
  total = 0
195
223
  total += INITIAL_WAIT unless @config[:poll_interval_average]
@@ -197,6 +225,11 @@ module Sidekiq
197
225
 
198
226
  @sleeper.pop(total)
199
227
  rescue Timeout::Error
228
+ ensure
229
+ # periodically clean out the `processes` set in Redis which can collect
230
+ # references to dead processes over time. The process count affects how
231
+ # often we scan for scheduled jobs.
232
+ cleanup
200
233
  end
201
234
  end
202
235
  end
@@ -51,19 +51,10 @@ module Sidekiq
51
51
  end
52
52
 
53
53
  def server_middleware
54
- @server_chain ||= Middleware::Chain.new
54
+ @server_chain ||= Middleware::Chain.new(Sidekiq.default_configuration)
55
55
  yield @server_chain if block_given?
56
56
  @server_chain
57
57
  end
58
-
59
- def constantize(str)
60
- names = str.split("::")
61
- names.shift if names.empty? || names.first.empty?
62
-
63
- names.inject(Object) do |constant, name|
64
- constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
65
- end
66
- end
67
58
  end
68
59
  end
69
60
 
@@ -83,7 +74,7 @@ module Sidekiq
83
74
  true
84
75
  elsif Sidekiq::Testing.inline?
85
76
  payloads.each do |job|
86
- klass = Sidekiq::Testing.constantize(job["class"])
77
+ klass = Object.const_get(job["class"])
87
78
  job["id"] ||= SecureRandom.hex(12)
88
79
  job_hash = Sidekiq.load_json(Sidekiq.dump_json(job))
89
80
  klass.process_job(job_hash)
@@ -218,26 +209,10 @@ module Sidekiq
218
209
  # assert_equal 1, HardJob.jobs.size
219
210
  # assert_equal :something, HardJob.jobs[0]['args'][0]
220
211
  #
221
- # assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
222
- # MyMailer.delay.send_welcome_email('foo@example.com')
223
- # assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
224
- #
225
212
  # You can also clear and drain all job types:
226
213
  #
227
- # assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
228
- # assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
229
- #
230
- # MyMailer.delay.send_welcome_email('foo@example.com')
231
- # MyModel.delay.do_something_hard
232
- #
233
- # assert_equal 1, Sidekiq::Extensions::DelayedMailer.jobs.size
234
- # assert_equal 1, Sidekiq::Extensions::DelayedModel.jobs.size
235
- #
236
214
  # Sidekiq::Worker.clear_all # or .drain_all
237
215
  #
238
- # assert_equal 0, Sidekiq::Extensions::DelayedMailer.jobs.size
239
- # assert_equal 0, Sidekiq::Extensions::DelayedModel.jobs.size
240
- #
241
216
  # This can be useful to make sure jobs don't linger between tests:
242
217
  #
243
218
  # RSpec.configure do |config|
@@ -318,7 +293,7 @@ module Sidekiq
318
293
  job_classes = jobs.map { |job| job["class"] }.uniq
319
294
 
320
295
  job_classes.each do |job_class|
321
- Sidekiq::Testing.constantize(job_class).drain
296
+ Object.const_get(job_class).drain
322
297
  end
323
298
  end
324
299
  end
@@ -329,13 +304,10 @@ module Sidekiq
329
304
  def jobs_for(klass)
330
305
  jobs.select do |job|
331
306
  marshalled = job["args"][0]
332
- marshalled.index(klass.to_s) && YAML.load(marshalled)[0] == klass
307
+ marshalled.index(klass.to_s) && YAML.safe_load(marshalled)[0] == klass
333
308
  end
334
309
  end
335
310
  end
336
-
337
- Sidekiq::Extensions::DelayedMailer.extend(TestingExtensions) if defined?(Sidekiq::Extensions::DelayedMailer)
338
- Sidekiq::Extensions::DelayedModel.extend(TestingExtensions) if defined?(Sidekiq::Extensions::DelayedModel)
339
311
  end
340
312
 
341
313
  if defined?(::Rails) && Rails.respond_to?(:env) && !Rails.env.test? && !$TESTING
@@ -5,8 +5,8 @@ require "sidekiq/client"
5
5
 
6
6
  module Sidekiq
7
7
  class TransactionAwareClient
8
- def initialize(redis_pool)
9
- @redis_client = Client.new(redis_pool)
8
+ def initialize(pool: nil, config: nil)
9
+ @redis_client = Client.new(pool: pool, config: config)
10
10
  end
11
11
 
12
12
  def push(item)
@@ -34,11 +34,10 @@ module Sidekiq
34
34
  begin
35
35
  require "after_commit_everywhere"
36
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
37
+ raise %q(You need to add `gem "after_commit_everywhere"` to your Gemfile to use Sidekiq's transactional client)
39
38
  end
40
39
 
41
- default_job_options["client_class"] = Sidekiq::TransactionAwareClient
40
+ Sidekiq.default_job_options["client_class"] = Sidekiq::TransactionAwareClient
42
41
  Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
43
42
  true
44
43
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sidekiq
4
- VERSION = "6.5.6"
4
+ VERSION = "7.0.0.beta1"
5
5
  end
@@ -307,7 +307,7 @@ module Sidekiq
307
307
  end
308
308
 
309
309
  get "/stats/queues" do
310
- json Sidekiq::Stats::Queues.new.lengths
310
+ json Sidekiq::Stats.new.queues
311
311
  end
312
312
 
313
313
  def call(env)
@@ -152,7 +152,7 @@ module Sidekiq
152
152
  # value and decrypt it
153
153
  token_length = masked_token.length / 2
154
154
  one_time_pad = masked_token[0...token_length]
155
- encrypted_token = masked_token[token_length..-1]
155
+ encrypted_token = masked_token[token_length..]
156
156
  xor_byte_strings(one_time_pad, encrypted_token)
157
157
  end
158
158
 
@@ -155,7 +155,7 @@ module Sidekiq
155
155
  @sorted_processes ||= begin
156
156
  return processes unless processes.all? { |p| p["hostname"] }
157
157
 
158
- split_characters = /[._-]/
158
+ split_characters = /[._-]+/
159
159
 
160
160
  padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
161
161
 
@@ -175,18 +175,14 @@ module Sidekiq
175
175
  @stats ||= Sidekiq::Stats.new
176
176
  end
177
177
 
178
- def redis_connection
178
+ def redis_url
179
179
  Sidekiq.redis do |conn|
180
- conn.connection[:id]
180
+ conn._config.server_url
181
181
  end
182
182
  end
183
183
 
184
- def namespace
185
- @ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
186
- end
187
-
188
184
  def redis_info
189
- Sidekiq.redis_info
185
+ Sidekiq.default_configuration.redis_info
190
186
  end
191
187
 
192
188
  def root_path
@@ -324,7 +320,7 @@ module Sidekiq
324
320
  end
325
321
 
326
322
  def environment_title_prefix
327
- environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
323
+ environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
328
324
 
329
325
  "[#{environment.upcase}] " unless environment == "production"
330
326
  end
@@ -337,13 +333,6 @@ module Sidekiq
337
333
  Time.now.utc.strftime("%H:%M:%S UTC")
338
334
  end
339
335
 
340
- def redis_connection_and_namespace
341
- @redis_connection_and_namespace ||= begin
342
- namespace_suffix = namespace.nil? ? "" : "##{namespace}"
343
- "#{redis_connection}#{namespace_suffix}"
344
- end
345
- end
346
-
347
336
  def retry_or_delete_or_kill(job, params)
348
337
  if params["retry"]
349
338
  job.retry
data/lib/sidekiq/web.rb CHANGED
@@ -30,13 +30,10 @@ module Sidekiq
30
30
  "Queues" => "queues",
31
31
  "Retries" => "retries",
32
32
  "Scheduled" => "scheduled",
33
- "Dead" => "morgue"
33
+ "Dead" => "morgue",
34
+ "Metrics" => "metrics"
34
35
  }
35
36
 
36
- if ENV["SIDEKIQ_METRICS_BETA"] == "1"
37
- DEFAULT_TABS["Metrics"] = "metrics"
38
- end
39
-
40
37
  class << self
41
38
  def settings
42
39
  self
@@ -79,14 +76,6 @@ module Sidekiq
79
76
  send(:"#{attribute}=", value)
80
77
  end
81
78
 
82
- def sessions=(val)
83
- puts "WARNING: Sidekiq::Web.sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
84
- end
85
-
86
- def session_secret=(val)
87
- puts "WARNING: Sidekiq::Web.session_secret= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
88
- end
89
-
90
79
  attr_accessor :app_url, :redis_pool
91
80
  attr_writer :locales, :views
92
81
  end
@@ -133,10 +122,6 @@ module Sidekiq
133
122
  send(:"#{attribute}=", value)
134
123
  end
135
124
 
136
- def sessions=(val)
137
- puts "Sidekiq::Web#sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller[2..2].first}"
138
- end
139
-
140
125
  def self.register(extension)
141
126
  extension.registered(WebApplication)
142
127
  end
@@ -0,0 +1,13 @@
1
+ require "sidekiq/job"
2
+
3
+ module Sidekiq
4
+ # Sidekiq::Job is a new alias for Sidekiq::Worker as of Sidekiq 6.3.0.
5
+ # Use `include Sidekiq::Job` rather than `include Sidekiq::Worker`.
6
+ #
7
+ # The term "worker" is too generic and overly confusing, used in several
8
+ # different contexts meaning different things. Many people call a Sidekiq
9
+ # process a "worker". Some people call the thread that executes jobs a
10
+ # "worker". This change brings Sidekiq closer to ActiveJob where your job
11
+ # classes extend ApplicationJob.
12
+ Worker = Job
13
+ end