sidekiq 6.5.12 → 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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +5 -24
  3. data/README.md +13 -12
  4. data/bin/sidekiq +3 -8
  5. data/bin/sidekiqload +14 -23
  6. data/lib/sidekiq/api.rb +51 -127
  7. data/lib/sidekiq/capsule.rb +110 -0
  8. data/lib/sidekiq/cli.rb +44 -59
  9. data/lib/sidekiq/client.rb +30 -17
  10. data/lib/sidekiq/component.rb +1 -0
  11. data/lib/sidekiq/config.rb +270 -0
  12. data/lib/sidekiq/deploy.rb +62 -0
  13. data/lib/sidekiq/embedded.rb +61 -0
  14. data/lib/sidekiq/fetch.rb +10 -11
  15. data/lib/sidekiq/job.rb +375 -10
  16. data/lib/sidekiq/job_logger.rb +1 -1
  17. data/lib/sidekiq/job_retry.rb +8 -8
  18. data/lib/sidekiq/job_util.rb +4 -4
  19. data/lib/sidekiq/launcher.rb +36 -46
  20. data/lib/sidekiq/logger.rb +1 -26
  21. data/lib/sidekiq/manager.rb +9 -11
  22. data/lib/sidekiq/metrics/query.rb +3 -3
  23. data/lib/sidekiq/metrics/shared.rb +4 -3
  24. data/lib/sidekiq/metrics/tracking.rb +18 -18
  25. data/lib/sidekiq/middleware/chain.rb +7 -9
  26. data/lib/sidekiq/middleware/current_attributes.rb +3 -8
  27. data/lib/sidekiq/monitor.rb +1 -1
  28. data/lib/sidekiq/paginator.rb +1 -9
  29. data/lib/sidekiq/pool.rb +7 -0
  30. data/lib/sidekiq/processor.rb +17 -26
  31. data/lib/sidekiq/rails.rb +11 -10
  32. data/lib/sidekiq/redis_client_adapter.rb +9 -45
  33. data/lib/sidekiq/redis_connection.rb +11 -111
  34. data/lib/sidekiq/scheduled.rb +19 -20
  35. data/lib/sidekiq/testing.rb +4 -32
  36. data/lib/sidekiq/transaction_aware_client.rb +4 -5
  37. data/lib/sidekiq/version.rb +1 -1
  38. data/lib/sidekiq/web/application.rb +1 -4
  39. data/lib/sidekiq/web/csrf_protection.rb +1 -1
  40. data/lib/sidekiq/web/helpers.rb +21 -22
  41. data/lib/sidekiq/web.rb +2 -17
  42. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  43. data/lib/sidekiq.rb +52 -274
  44. data/sidekiq.gemspec +29 -5
  45. data/web/assets/javascripts/application.js +0 -1
  46. data/web/assets/javascripts/base-charts.js +106 -0
  47. data/web/assets/javascripts/dashboard-charts.js +166 -0
  48. data/web/assets/javascripts/dashboard.js +3 -223
  49. data/web/assets/javascripts/metrics.js +90 -116
  50. data/web/assets/stylesheets/application-rtl.css +2 -91
  51. data/web/assets/stylesheets/application.css +21 -296
  52. data/web/locales/ar.yml +70 -70
  53. data/web/locales/cs.yml +62 -62
  54. data/web/locales/da.yml +52 -52
  55. data/web/locales/de.yml +65 -65
  56. data/web/locales/el.yml +2 -7
  57. data/web/locales/en.yml +76 -70
  58. data/web/locales/es.yml +68 -68
  59. data/web/locales/fa.yml +65 -65
  60. data/web/locales/fr.yml +67 -67
  61. data/web/locales/he.yml +65 -64
  62. data/web/locales/hi.yml +59 -59
  63. data/web/locales/it.yml +53 -53
  64. data/web/locales/ja.yml +64 -68
  65. data/web/locales/ko.yml +52 -52
  66. data/web/locales/lt.yml +66 -66
  67. data/web/locales/nb.yml +61 -61
  68. data/web/locales/nl.yml +52 -52
  69. data/web/locales/pl.yml +45 -45
  70. data/web/locales/pt-br.yml +59 -69
  71. data/web/locales/pt.yml +51 -51
  72. data/web/locales/ru.yml +67 -66
  73. data/web/locales/sv.yml +53 -53
  74. data/web/locales/ta.yml +60 -60
  75. data/web/locales/uk.yml +62 -61
  76. data/web/locales/ur.yml +64 -64
  77. data/web/locales/vi.yml +67 -67
  78. data/web/locales/zh-cn.yml +1 -0
  79. data/web/locales/zh-tw.yml +10 -1
  80. data/web/views/_footer.erb +5 -2
  81. data/web/views/busy.erb +1 -6
  82. data/web/views/dashboard.erb +36 -5
  83. data/web/views/metrics.erb +30 -19
  84. data/web/views/metrics_for_job.erb +16 -34
  85. metadata +60 -37
  86. data/lib/sidekiq/delay.rb +0 -43
  87. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  88. data/lib/sidekiq/extensions/active_record.rb +0 -43
  89. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  90. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  91. data/lib/sidekiq/metrics/deploy.rb +0 -47
  92. data/lib/sidekiq/worker.rb +0 -370
  93. data/web/assets/javascripts/graph.js +0 -16
  94. /data/{LICENSE → LICENSE.txt} +0 -0
@@ -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
@@ -194,11 +193,11 @@ module Sidekiq
194
193
  # should never depend on sidekiq/api.
195
194
  def cleanup
196
195
  # dont run cleanup more than once per minute
197
- return 0 unless Sidekiq.redis { |conn| conn.set("process_cleanup", "1", nx: true, ex: 60) }
196
+ return 0 unless redis { |conn| conn.set("process_cleanup", "1", nx: true, ex: 60) }
198
197
 
199
198
  count = 0
200
- Sidekiq.redis do |conn|
201
- procs = conn.sscan_each("processes").to_a
199
+ redis do |conn|
200
+ procs = conn.sscan("processes").to_a
202
201
  heartbeats = conn.pipelined { |pipeline|
203
202
  procs.each do |key|
204
203
  pipeline.hget(key, "info")
@@ -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.12"
4
+ VERSION = "7.0.0.beta1"
5
5
  end
@@ -74,9 +74,6 @@ module Sidekiq
74
74
  end
75
75
 
76
76
  get "/busy" do
77
- @count = (params["count"] || 100).to_i
78
- (@current_page, @total_size, @workset) = page_items(workset, params["page"], @count)
79
-
80
77
  erb(:busy)
81
78
  end
82
79
 
@@ -310,7 +307,7 @@ module Sidekiq
310
307
  end
311
308
 
312
309
  get "/stats/queues" do
313
- json Sidekiq::Stats::Queues.new.lengths
310
+ json Sidekiq::Stats.new.queues
314
311
  end
315
312
 
316
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
 
@@ -137,7 +137,7 @@ module Sidekiq
137
137
  end
138
138
 
139
139
  def sort_direction_label
140
- (params[:direction] == "asc") ? "&uarr;" : "&darr;"
140
+ params[:direction] == "asc" ? "&uarr;" : "&darr;"
141
141
  end
142
142
 
143
143
  def workset
@@ -148,15 +148,25 @@ module Sidekiq
148
148
  @processes ||= Sidekiq::ProcessSet.new
149
149
  end
150
150
 
151
- # Sorts processes by hostname following the natural sort order
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'
152
154
  def sorted_processes
153
155
  @sorted_processes ||= begin
154
156
  return processes unless processes.all? { |p| p["hostname"] }
155
157
 
158
+ split_characters = /[._-]+/
159
+
160
+ padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
161
+
156
162
  processes.to_a.sort_by do |process|
157
- # Kudos to `shurikk` on StackOverflow
158
- # https://stackoverflow.com/a/15170063/575547
159
- process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
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
160
170
  end
161
171
  end
162
172
  end
@@ -165,18 +175,14 @@ module Sidekiq
165
175
  @stats ||= Sidekiq::Stats.new
166
176
  end
167
177
 
168
- def redis_connection
178
+ def redis_url
169
179
  Sidekiq.redis do |conn|
170
- conn.connection[:id]
180
+ conn._config.server_url
171
181
  end
172
182
  end
173
183
 
174
- def namespace
175
- @ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
176
- end
177
-
178
184
  def redis_info
179
- Sidekiq.redis_info
185
+ Sidekiq.default_configuration.redis_info
180
186
  end
181
187
 
182
188
  def root_path
@@ -188,7 +194,7 @@ module Sidekiq
188
194
  end
189
195
 
190
196
  def current_status
191
- (workset.size == 0) ? "idle" : "active"
197
+ workset.size == 0 ? "idle" : "active"
192
198
  end
193
199
 
194
200
  def relative_time(time)
@@ -221,7 +227,7 @@ module Sidekiq
221
227
  end
222
228
 
223
229
  def truncate(text, truncate_after_chars = 2000)
224
- (truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
230
+ truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
225
231
  end
226
232
 
227
233
  def display_args(args, truncate_after_chars = 2000)
@@ -314,7 +320,7 @@ module Sidekiq
314
320
  end
315
321
 
316
322
  def environment_title_prefix
317
- 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"
318
324
 
319
325
  "[#{environment.upcase}] " unless environment == "production"
320
326
  end
@@ -327,13 +333,6 @@ module Sidekiq
327
333
  Time.now.utc.strftime("%H:%M:%S UTC")
328
334
  end
329
335
 
330
- def redis_connection_and_namespace
331
- @redis_connection_and_namespace ||= begin
332
- namespace_suffix = namespace.nil? ? "" : "##{namespace}"
333
- "#{redis_connection}#{namespace_suffix}"
334
- end
335
- end
336
-
337
336
  def retry_or_delete_or_kill(job, params)
338
337
  if params["retry"]
339
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