sidekiq 6.4.2 → 6.5.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +89 -0
  3. data/bin/sidekiqload +17 -5
  4. data/lib/sidekiq/api.rb +196 -45
  5. data/lib/sidekiq/cli.rb +46 -32
  6. data/lib/sidekiq/client.rb +6 -6
  7. data/lib/sidekiq/component.rb +65 -0
  8. data/lib/sidekiq/delay.rb +1 -1
  9. data/lib/sidekiq/fetch.rb +18 -16
  10. data/lib/sidekiq/job_retry.rb +60 -39
  11. data/lib/sidekiq/job_util.rb +7 -3
  12. data/lib/sidekiq/launcher.rb +24 -21
  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 +153 -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 +18 -12
  21. data/lib/sidekiq/middleware/i18n.rb +2 -0
  22. data/lib/sidekiq/middleware/modules.rb +21 -0
  23. data/lib/sidekiq/monitor.rb +1 -1
  24. data/lib/sidekiq/paginator.rb +11 -3
  25. data/lib/sidekiq/processor.rb +21 -15
  26. data/lib/sidekiq/rails.rb +12 -13
  27. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  28. data/lib/sidekiq/redis_connection.rb +78 -47
  29. data/lib/sidekiq/ring_buffer.rb +29 -0
  30. data/lib/sidekiq/scheduled.rb +53 -24
  31. data/lib/sidekiq/testing.rb +1 -1
  32. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  33. data/lib/sidekiq/version.rb +1 -1
  34. data/lib/sidekiq/web/action.rb +3 -3
  35. data/lib/sidekiq/web/application.rb +21 -5
  36. data/lib/sidekiq/web/helpers.rb +18 -5
  37. data/lib/sidekiq/web.rb +5 -1
  38. data/lib/sidekiq/worker.rb +8 -4
  39. data/lib/sidekiq.rb +87 -18
  40. data/sidekiq.gemspec +2 -2
  41. data/web/assets/javascripts/application.js +2 -1
  42. data/web/assets/javascripts/chart.min.js +13 -0
  43. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  44. data/web/assets/javascripts/dashboard.js +0 -17
  45. data/web/assets/javascripts/graph.js +16 -0
  46. data/web/assets/javascripts/metrics.js +262 -0
  47. data/web/assets/stylesheets/application.css +44 -1
  48. data/web/locales/el.yml +43 -19
  49. data/web/locales/en.yml +7 -0
  50. data/web/locales/ja.yml +7 -0
  51. data/web/locales/pt-br.yml +27 -9
  52. data/web/locales/zh-cn.yml +36 -11
  53. data/web/locales/zh-tw.yml +32 -7
  54. data/web/views/_nav.erb +1 -1
  55. data/web/views/busy.erb +7 -2
  56. data/web/views/dashboard.erb +1 -0
  57. data/web/views/metrics.erb +69 -0
  58. data/web/views/metrics_for_job.erb +87 -0
  59. data/web/views/queue.erb +5 -1
  60. metadata +34 -9
  61. data/lib/sidekiq/exception_handler.rb +0 -27
  62. data/lib/sidekiq/util.rb +0 -108
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"
26
- gem.add_dependency "connection_pool", ">= 2.2.2"
25
+ gem.add_dependency "redis", ["<5", ">= 4.5.0"]
26
+ gem.add_dependency "connection_pool", ["<3", ">= 2.2.5"]
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 {
@@ -122,6 +122,7 @@ function checkResponse(resp) {
122
122
 
123
123
  function scheduleLivePoll() {
124
124
  let ti = parseInt(localStorage.sidekiqTimeInterval) || 5000;
125
+ if (ti < 2000) { ti = 2000 }
125
126
  livePollTimer = setTimeout(livePollCallback, ti);
126
127
  }
127
128