sidekiq 5.2.3 → 6.0.0

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 (64) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +61 -0
  3. data/.gitignore +1 -1
  4. data/.standard.yml +20 -0
  5. data/6.0-Upgrade.md +70 -0
  6. data/COMM-LICENSE +11 -9
  7. data/Changes.md +61 -0
  8. data/Ent-2.0-Upgrade.md +37 -0
  9. data/Ent-Changes.md +27 -1
  10. data/Gemfile +19 -9
  11. data/Gemfile.lock +196 -0
  12. data/Pro-5.0-Upgrade.md +25 -0
  13. data/Pro-Changes.md +19 -2
  14. data/README.md +17 -31
  15. data/Rakefile +6 -4
  16. data/bin/sidekiqload +27 -23
  17. data/bin/sidekiqmon +9 -0
  18. data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
  19. data/lib/generators/sidekiq/worker_generator.rb +12 -14
  20. data/lib/sidekiq.rb +56 -43
  21. data/lib/sidekiq/api.rb +138 -151
  22. data/lib/sidekiq/cli.rb +141 -206
  23. data/lib/sidekiq/client.rb +45 -46
  24. data/lib/sidekiq/delay.rb +5 -6
  25. data/lib/sidekiq/exception_handler.rb +10 -12
  26. data/lib/sidekiq/extensions/action_mailer.rb +10 -20
  27. data/lib/sidekiq/extensions/active_record.rb +9 -7
  28. data/lib/sidekiq/extensions/class_methods.rb +9 -7
  29. data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
  30. data/lib/sidekiq/fetch.rb +5 -6
  31. data/lib/sidekiq/job_logger.rb +37 -7
  32. data/lib/sidekiq/job_retry.rb +55 -57
  33. data/lib/sidekiq/launcher.rb +59 -51
  34. data/lib/sidekiq/logger.rb +69 -0
  35. data/lib/sidekiq/manager.rb +7 -9
  36. data/lib/sidekiq/middleware/chain.rb +3 -2
  37. data/lib/sidekiq/middleware/i18n.rb +5 -7
  38. data/lib/sidekiq/monitor.rb +148 -0
  39. data/lib/sidekiq/paginator.rb +11 -12
  40. data/lib/sidekiq/processor.rb +68 -58
  41. data/lib/sidekiq/rails.rb +24 -29
  42. data/lib/sidekiq/redis_connection.rb +31 -37
  43. data/lib/sidekiq/scheduled.rb +17 -19
  44. data/lib/sidekiq/testing.rb +22 -23
  45. data/lib/sidekiq/testing/inline.rb +2 -1
  46. data/lib/sidekiq/util.rb +17 -14
  47. data/lib/sidekiq/version.rb +2 -1
  48. data/lib/sidekiq/web.rb +41 -49
  49. data/lib/sidekiq/web/action.rb +14 -10
  50. data/lib/sidekiq/web/application.rb +61 -58
  51. data/lib/sidekiq/web/helpers.rb +72 -66
  52. data/lib/sidekiq/web/router.rb +17 -14
  53. data/lib/sidekiq/worker.rb +134 -102
  54. data/sidekiq.gemspec +16 -18
  55. data/web/assets/javascripts/dashboard.js +2 -21
  56. data/web/assets/stylesheets/bootstrap.css +1 -1
  57. data/web/locales/ja.yml +2 -1
  58. data/web/views/queues.erb +1 -1
  59. metadata +31 -26
  60. data/.travis.yml +0 -14
  61. data/bin/sidekiqctl +0 -237
  62. data/lib/sidekiq/core_ext.rb +0 -1
  63. data/lib/sidekiq/logging.rb +0 -122
  64. data/lib/sidekiq/middleware/server/active_record.rb +0 -23
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
- require 'uri'
3
- require 'set'
4
- require 'yaml'
5
- require 'cgi'
2
+
3
+ require "uri"
4
+ require "set"
5
+ require "yaml"
6
+ require "cgi"
6
7
 
7
8
  module Sidekiq
8
9
  # This is not a public API
9
10
  module WebHelpers
10
11
  def strings(lang)
11
- @@strings ||= {}
12
- @@strings[lang] ||= begin
12
+ @strings ||= {}
13
+ @strings[lang] ||= begin
13
14
  # Allow sidekiq-web extensions to add locale paths
14
15
  # so extensions can be localized
15
16
  settings.locales.each_with_object({}) do |path, global|
@@ -22,19 +23,19 @@ module Sidekiq
22
23
  end
23
24
 
24
25
  def clear_caches
25
- @@strings = nil
26
- @@locale_files = nil
27
- @@available_locales = nil
26
+ @strings = nil
27
+ @locale_files = nil
28
+ @available_locales = nil
28
29
  end
29
30
 
30
31
  def locale_files
31
- @@locale_files ||= settings.locales.flat_map do |path|
32
+ @locale_files ||= settings.locales.flat_map { |path|
32
33
  Dir["#{path}/*.yml"]
33
- end
34
+ }
34
35
  end
35
36
 
36
37
  def available_locales
37
- @@available_locales ||= locale_files.map { |path| File.basename(path, '.yml') }.uniq
38
+ @available_locales ||= locale_files.map { |path| File.basename(path, ".yml") }.uniq
38
39
  end
39
40
 
40
41
  def find_locale_files(lang)
@@ -63,7 +64,7 @@ module Sidekiq
63
64
  end
64
65
 
65
66
  def poll_path
66
- if current_path != '' && params['poll']
67
+ if current_path != "" && params["poll"]
67
68
  root_path + current_path
68
69
  else
69
70
  ""
@@ -71,24 +72,24 @@ module Sidekiq
71
72
  end
72
73
 
73
74
  def text_direction
74
- get_locale['TextDirection'] || 'ltr'
75
+ get_locale["TextDirection"] || "ltr"
75
76
  end
76
77
 
77
78
  def rtl?
78
- text_direction == 'rtl'
79
+ text_direction == "rtl"
79
80
  end
80
81
 
81
82
  # See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
82
83
  def user_preferred_languages
83
- languages = env['HTTP_ACCEPT_LANGUAGE']
84
- languages.to_s.downcase.gsub(/\s+/, '').split(',').map do |language|
85
- locale, quality = language.split(';q=', 2)
86
- locale = nil if locale == '*' # Ignore wildcards
84
+ languages = env["HTTP_ACCEPT_LANGUAGE"]
85
+ languages.to_s.downcase.gsub(/\s+/, "").split(",").map { |language|
86
+ locale, quality = language.split(";q=", 2)
87
+ locale = nil if locale == "*" # Ignore wildcards
87
88
  quality = quality ? quality.to_f : 1.0
88
89
  [locale, quality]
89
- end.sort do |(_, left), (_, right)|
90
+ }.sort { |(_, left), (_, right)|
90
91
  right <=> left
91
- end.map(&:first).compact
92
+ }.map(&:first).compact
92
93
  end
93
94
 
94
95
  # Given an Accept-Language header like "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2"
@@ -97,31 +98,31 @@ module Sidekiq
97
98
  # Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
98
99
  def locale
99
100
  @locale ||= begin
100
- matched_locale = user_preferred_languages.map do |preferred|
101
- preferred_language = preferred.split('-', 2).first
101
+ matched_locale = user_preferred_languages.map { |preferred|
102
+ preferred_language = preferred.split("-", 2).first
102
103
 
103
- lang_group = available_locales.select do |available|
104
- preferred_language == available.split('-', 2).first
105
- end
104
+ lang_group = available_locales.select { |available|
105
+ preferred_language == available.split("-", 2).first
106
+ }
106
107
 
107
108
  lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
108
- end.compact.first
109
+ }.compact.first
109
110
 
110
- matched_locale || 'en'
111
+ matched_locale || "en"
111
112
  end
112
113
  end
113
114
 
114
115
  # mperham/sidekiq#3243
115
116
  def unfiltered?
116
- yield unless env['PATH_INFO'].start_with?("/filter/")
117
+ yield unless env["PATH_INFO"].start_with?("/filter/")
117
118
  end
118
119
 
119
120
  def get_locale
120
121
  strings(locale)
121
122
  end
122
123
 
123
- def t(msg, options={})
124
- string = get_locale[msg] || strings('en')[msg] || msg
124
+ def t(msg, options = {})
125
+ string = get_locale[msg] || strings("en")[msg] || msg
125
126
  if options.empty?
126
127
  string
127
128
  else
@@ -142,9 +143,9 @@ module Sidekiq
142
143
  end
143
144
 
144
145
  def retries_with_score(score)
145
- Sidekiq.redis do |conn|
146
- conn.zrangebyscore('retry', score, score)
147
- end.map { |msg| Sidekiq.load_json(msg) }
146
+ Sidekiq.redis { |conn|
147
+ conn.zrangebyscore("retry", score, score)
148
+ }.map { |msg| Sidekiq.load_json(msg) }
148
149
  end
149
150
 
150
151
  def redis_connection
@@ -163,24 +164,24 @@ module Sidekiq
163
164
  end
164
165
 
165
166
  def root_path
166
- "#{env['SCRIPT_NAME']}/"
167
+ "#{env["SCRIPT_NAME"]}/"
167
168
  end
168
169
 
169
170
  def current_path
170
- @current_path ||= request.path_info.gsub(/^\//,'')
171
+ @current_path ||= request.path_info.gsub(/^\//, "")
171
172
  end
172
173
 
173
174
  def current_status
174
- workers.size == 0 ? 'idle' : 'active'
175
+ workers.size == 0 ? "idle" : "active"
175
176
  end
176
177
 
177
178
  def relative_time(time)
178
179
  stamp = time.getutc.iso8601
179
- %{<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>}
180
+ %(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
180
181
  end
181
182
 
182
183
  def job_params(job, score)
183
- "#{score}-#{job['jid']}"
184
+ "#{score}-#{job["jid"]}"
184
185
  end
185
186
 
186
187
  def parse_params(params)
@@ -188,7 +189,7 @@ module Sidekiq
188
189
  [score.to_f, jid]
189
190
  end
190
191
 
191
- SAFE_QPARAMS = %w(page poll)
192
+ SAFE_QPARAMS = %w[page poll]
192
193
 
193
194
  # Merge options with current params, filter safe params, and stringify to query string
194
195
  def qparams(options)
@@ -197,9 +198,9 @@ module Sidekiq
197
198
  options[key.to_s] = options.delete(key)
198
199
  end
199
200
 
200
- params.merge(options).map do |key, value|
201
+ params.merge(options).map { |key, value|
201
202
  SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
202
- end.compact.join("&")
203
+ }.compact.join("&")
203
204
  end
204
205
 
205
206
  def truncate(text, truncate_after_chars = 2000)
@@ -207,9 +208,16 @@ module Sidekiq
207
208
  end
208
209
 
209
210
  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(", ")
211
+ return "Invalid job payload, args is nil" if args.nil?
212
+ return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
213
+
214
+ begin
215
+ args.map { |arg|
216
+ h(truncate(to_display(arg), truncate_after_chars))
217
+ }.join(", ")
218
+ rescue
219
+ "Illegal job arguments: #{h args.inspect}"
220
+ end
213
221
  end
214
222
 
215
223
  def csrf_tag
@@ -217,23 +225,21 @@ module Sidekiq
217
225
  end
218
226
 
219
227
  def to_display(arg)
228
+ arg.inspect
229
+ rescue
220
230
  begin
221
- arg.inspect
222
- rescue
223
- begin
224
- arg.to_s
225
- rescue => ex
226
- "Cannot display argument: [#{ex.class.name}] #{ex.message}"
227
- end
231
+ arg.to_s
232
+ rescue => ex
233
+ "Cannot display argument: [#{ex.class.name}] #{ex.message}"
228
234
  end
229
235
  end
230
236
 
231
- RETRY_JOB_KEYS = Set.new(%w(
237
+ RETRY_JOB_KEYS = Set.new(%w[
232
238
  queue class args retry_count retried_at failed_at
233
239
  jid error_message error_class backtrace
234
240
  error_backtrace enqueued_at retry wrapped
235
241
  created_at
236
- ))
242
+ ])
237
243
 
238
244
  def retry_extra_items(retry_job)
239
245
  @retry_extra_items ||= {}.tap do |extra|
@@ -250,8 +256,8 @@ module Sidekiq
250
256
  return number
251
257
  end
252
258
 
253
- options = {delimiter: ',', separator: '.'}
254
- parts = number.to_s.to_str.split('.')
259
+ options = {delimiter: ",", separator: "."}
260
+ parts = number.to_s.to_str.split(".")
255
261
  parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
256
262
  parts.join(options[:separator])
257
263
  end
@@ -259,8 +265,8 @@ module Sidekiq
259
265
  def h(text)
260
266
  ::Rack::Utils.escape_html(text)
261
267
  rescue ArgumentError => e
262
- raise unless e.message.eql?('invalid byte sequence in UTF-8')
263
- text.encode!('UTF-16', 'UTF-8', invalid: :replace, replace: '').encode!('UTF-8', 'UTF-16')
268
+ raise unless e.message.eql?("invalid byte sequence in UTF-8")
269
+ text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
264
270
  retry
265
271
  end
266
272
 
@@ -277,7 +283,7 @@ module Sidekiq
277
283
  end
278
284
 
279
285
  def environment_title_prefix
280
- environment = Sidekiq.options[:environment] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
286
+ environment = Sidekiq.options[:environment] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
281
287
 
282
288
  "[#{environment.upcase}] " unless environment == "production"
283
289
  end
@@ -287,30 +293,30 @@ module Sidekiq
287
293
  end
288
294
 
289
295
  def server_utc_time
290
- Time.now.utc.strftime('%H:%M:%S UTC')
296
+ Time.now.utc.strftime("%H:%M:%S UTC")
291
297
  end
292
298
 
293
299
  def redis_connection_and_namespace
294
300
  @redis_connection_and_namespace ||= begin
295
- namespace_suffix = namespace == nil ? '' : "##{namespace}"
301
+ namespace_suffix = namespace.nil? ? "" : "##{namespace}"
296
302
  "#{redis_connection}#{namespace_suffix}"
297
303
  end
298
304
  end
299
305
 
300
306
  def retry_or_delete_or_kill(job, params)
301
- if params['retry']
307
+ if params["retry"]
302
308
  job.retry
303
- elsif params['delete']
309
+ elsif params["delete"]
304
310
  job.delete
305
- elsif params['kill']
311
+ elsif params["kill"]
306
312
  job.kill
307
313
  end
308
314
  end
309
315
 
310
316
  def delete_or_add_queue(job, params)
311
- if params['delete']
317
+ if params["delete"]
312
318
  job.delete
313
- elsif params['add_to_queue']
319
+ elsif params["add_to_queue"]
314
320
  job.add_to_queue
315
321
  end
316
322
  end
@@ -1,18 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require 'rack'
2
+
3
+ require "rack"
3
4
 
4
5
  module Sidekiq
5
6
  module WebRouter
6
- GET = 'GET'
7
- DELETE = 'DELETE'
8
- POST = 'POST'
9
- PUT = 'PUT'
10
- PATCH = 'PATCH'
11
- HEAD = 'HEAD'
7
+ GET = "GET"
8
+ DELETE = "DELETE"
9
+ POST = "POST"
10
+ PUT = "PUT"
11
+ PATCH = "PATCH"
12
+ HEAD = "HEAD"
12
13
 
13
- ROUTE_PARAMS = 'rack.route_params'
14
- REQUEST_METHOD = 'REQUEST_METHOD'
15
- PATH_INFO = 'PATH_INFO'
14
+ ROUTE_PARAMS = "rack.route_params"
15
+ REQUEST_METHOD = "REQUEST_METHOD"
16
+ PATH_INFO = "PATH_INFO"
16
17
 
17
18
  def get(path, &block)
18
19
  route(GET, path, &block)
@@ -35,7 +36,7 @@ module Sidekiq
35
36
  end
36
37
 
37
38
  def route(method, path, &block)
38
- @routes ||= { GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => [] }
39
+ @routes ||= {GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => []}
39
40
 
40
41
  @routes[method] << WebRoute.new(method, path, block)
41
42
  @routes[HEAD] << WebRoute.new(method, path, block) if method == GET
@@ -50,7 +51,8 @@ module Sidekiq
50
51
  path_info = "/" if path_info == ""
51
52
 
52
53
  @routes[request_method].each do |route|
53
- if params = route.match(request_method, path_info)
54
+ params = route.match(request_method, path_info)
55
+ if params
54
56
  env[ROUTE_PARAMS] = params
55
57
 
56
58
  return WebAction.new(env, route.block)
@@ -77,7 +79,7 @@ module Sidekiq
77
79
  end
78
80
 
79
81
  def compile
80
- if pattern.match(NAMED_SEGMENTS_PATTERN)
82
+ if pattern.match?(NAMED_SEGMENTS_PATTERN)
81
83
  p = pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^$/]+)')
82
84
 
83
85
  Regexp.new("\\A#{p}\\Z")
@@ -91,7 +93,8 @@ module Sidekiq
91
93
  when String
92
94
  {} if path == matcher
93
95
  else
94
- if path_match = path.match(matcher)
96
+ path_match = path.match(matcher)
97
+ if path_match
95
98
  Hash[path_match.names.map(&:to_sym).zip(path_match.captures)]
96
99
  end
97
100
  end
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
- require 'sidekiq/client'
3
2
 
4
- module Sidekiq
3
+ require "sidekiq/client"
5
4
 
5
+ module Sidekiq
6
6
  ##
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
  #
@@ -21,15 +21,124 @@ module Sidekiq
21
21
  #
22
22
  # Note that perform_async is a class method, perform is an instance method.
23
23
  module Worker
24
+ ##
25
+ # The Options module is extracted so we can include it in ActiveJob::Base
26
+ # and allow native AJs to configure Sidekiq features/internals.
27
+ module Options
28
+ def self.included(base)
29
+ base.extend(ClassMethods)
30
+ base.sidekiq_class_attribute :sidekiq_options_hash
31
+ base.sidekiq_class_attribute :sidekiq_retry_in_block
32
+ base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
33
+ end
34
+
35
+ module ClassMethods
36
+ ACCESSOR_MUTEX = Mutex.new
37
+
38
+ ##
39
+ # Allows customization for this type of Worker.
40
+ # Legal options:
41
+ #
42
+ # queue - name of queue to use for this job type, default *default*
43
+ # retry - enable retries for this Worker in case of error during execution,
44
+ # *true* to use the default or *Integer* count
45
+ # backtrace - whether to save any error backtrace in the retry payload to display in web UI,
46
+ # can be true, false or an integer number of lines to save, default *false*
47
+ #
48
+ # In practice, any option is allowed. This is the main mechanism to configure the
49
+ # options for a specific job.
50
+ def sidekiq_options(opts = {})
51
+ opts = Hash[opts.map { |k, v| [k.to_s, v] }] # stringify
52
+ self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map { |k, v| [k.to_s, v] }])
53
+ end
54
+
55
+ def sidekiq_retry_in(&block)
56
+ self.sidekiq_retry_in_block = block
57
+ end
58
+
59
+ def sidekiq_retries_exhausted(&block)
60
+ self.sidekiq_retries_exhausted_block = block
61
+ end
62
+
63
+ def get_sidekiq_options # :nodoc:
64
+ self.sidekiq_options_hash ||= Sidekiq.default_worker_options
65
+ end
66
+
67
+ def sidekiq_class_attribute(*attrs)
68
+ instance_reader = true
69
+ instance_writer = true
70
+
71
+ attrs.each do |name|
72
+ synchronized_getter = "__synchronized_#{name}"
73
+
74
+ singleton_class.instance_eval do
75
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
76
+ end
77
+
78
+ define_singleton_method(synchronized_getter) { nil }
79
+ singleton_class.class_eval do
80
+ private(synchronized_getter)
81
+ end
82
+
83
+ define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
84
+
85
+ ivar = "@#{name}"
86
+
87
+ singleton_class.instance_eval do
88
+ m = "#{name}="
89
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
90
+ end
91
+ define_singleton_method("#{name}=") do |val|
92
+ singleton_class.class_eval do
93
+ ACCESSOR_MUTEX.synchronize do
94
+ undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
95
+ define_method(synchronized_getter) { val }
96
+ end
97
+ end
98
+
99
+ if singleton_class?
100
+ class_eval do
101
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
102
+ define_method(name) do
103
+ if instance_variable_defined? ivar
104
+ instance_variable_get ivar
105
+ else
106
+ singleton_class.send name
107
+ end
108
+ end
109
+ end
110
+ end
111
+ val
112
+ end
113
+
114
+ if instance_reader
115
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
116
+ define_method(name) do
117
+ if instance_variable_defined?(ivar)
118
+ instance_variable_get ivar
119
+ else
120
+ self.class.public_send name
121
+ end
122
+ end
123
+ end
124
+
125
+ if instance_writer
126
+ m = "#{name}="
127
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
128
+ attr_writer name
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+
24
135
  attr_accessor :jid
25
136
 
26
137
  def self.included(base)
27
- raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? {|c| c.name == 'ActiveJob::Base' }
138
+ raise ArgumentError, "Sidekiq::Worker cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
28
139
 
140
+ base.include(Options)
29
141
  base.extend(ClassMethods)
30
- base.sidekiq_class_attribute :sidekiq_options_hash
31
- base.sidekiq_class_attribute :sidekiq_retry_in_block
32
- base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
33
142
  end
34
143
 
35
144
  def logger
@@ -46,8 +155,13 @@ module Sidekiq
46
155
  @opts = opts
47
156
  end
48
157
 
158
+ def set(options)
159
+ @opts.merge!(options)
160
+ self
161
+ end
162
+
49
163
  def perform_async(*args)
50
- @klass.client_push(@opts.merge('args' => args, 'class' => @klass))
164
+ @klass.client_push(@opts.merge("args" => args, "class" => @klass))
51
165
  end
52
166
 
53
167
  # +interval+ must be a timestamp, numeric or something that acts
@@ -57,17 +171,15 @@ module Sidekiq
57
171
  now = Time.now.to_f
58
172
  ts = (int < 1_000_000_000 ? now + int : int)
59
173
 
60
- payload = @opts.merge('class' => @klass, 'args' => args, 'at' => ts)
174
+ payload = @opts.merge("class" => @klass, "args" => args, "at" => ts)
61
175
  # Optimization to enqueue something now that is scheduled to go out now or in the past
62
- payload.delete('at') if ts <= now
176
+ payload.delete("at") if ts <= now
63
177
  @klass.client_push(payload)
64
178
  end
65
179
  alias_method :perform_at, :perform_in
66
180
  end
67
181
 
68
182
  module ClassMethods
69
- ACCESSOR_MUTEX = Mutex.new
70
-
71
183
  def delay(*args)
72
184
  raise ArgumentError, "Do not call .delay on a Sidekiq::Worker class, call .perform_async"
73
185
  end
@@ -85,7 +197,7 @@ module Sidekiq
85
197
  end
86
198
 
87
199
  def perform_async(*args)
88
- client_push('class' => self, 'args' => args)
200
+ client_push("class" => self, "args" => args)
89
201
  end
90
202
 
91
203
  # +interval+ must be a timestamp, numeric or something that acts
@@ -95,10 +207,10 @@ module Sidekiq
95
207
  now = Time.now.to_f
96
208
  ts = (int < 1_000_000_000 ? now + int : int)
97
209
 
98
- item = { 'class' => self, 'args' => args, 'at' => ts }
210
+ item = {"class" => self, "args" => args, "at" => ts}
99
211
 
100
212
  # Optimization to enqueue something now that is scheduled to go out now or in the past
101
- item.delete('at') if ts <= now
213
+ item.delete("at") if ts <= now
102
214
 
103
215
  client_push(item)
104
216
  end
@@ -117,25 +229,12 @@ module Sidekiq
117
229
  #
118
230
  # In practice, any option is allowed. This is the main mechanism to configure the
119
231
  # options for a specific job.
120
- def sidekiq_options(opts={})
121
- # stringify
122
- self.sidekiq_options_hash = get_sidekiq_options.merge(Hash[opts.map{|k, v| [k.to_s, v]}])
123
- end
124
-
125
- def sidekiq_retry_in(&block)
126
- self.sidekiq_retry_in_block = block
127
- end
128
-
129
- def sidekiq_retries_exhausted(&block)
130
- self.sidekiq_retries_exhausted_block = block
131
- end
132
-
133
- def get_sidekiq_options # :nodoc:
134
- self.sidekiq_options_hash ||= Sidekiq.default_worker_options
232
+ def sidekiq_options(opts = {})
233
+ super
135
234
  end
136
235
 
137
236
  def client_push(item) # :nodoc:
138
- pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options['pool'] || Sidekiq.redis_pool
237
+ pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
139
238
  # stringify
140
239
  item.keys.each do |key|
141
240
  item[key.to_s] = item.delete(key)
@@ -143,73 +242,6 @@ module Sidekiq
143
242
 
144
243
  Sidekiq::Client.new(pool).push(item)
145
244
  end
146
-
147
- def sidekiq_class_attribute(*attrs)
148
- instance_reader = true
149
- instance_writer = true
150
-
151
- attrs.each do |name|
152
- synchronized_getter = "__synchronized_#{name}"
153
-
154
- singleton_class.instance_eval do
155
- undef_method(name) if method_defined?(name) || private_method_defined?(name)
156
- end
157
-
158
- define_singleton_method(synchronized_getter) { nil }
159
- singleton_class.class_eval do
160
- private(synchronized_getter)
161
- end
162
-
163
- define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
164
-
165
- ivar = "@#{name}"
166
-
167
- singleton_class.instance_eval do
168
- m = "#{name}="
169
- undef_method(m) if method_defined?(m) || private_method_defined?(m)
170
- end
171
- define_singleton_method("#{name}=") do |val|
172
- singleton_class.class_eval do
173
- ACCESSOR_MUTEX.synchronize do
174
- undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
175
- define_method(synchronized_getter) { val }
176
- end
177
- end
178
-
179
- if singleton_class?
180
- class_eval do
181
- undef_method(name) if method_defined?(name) || private_method_defined?(name)
182
- define_method(name) do
183
- if instance_variable_defined? ivar
184
- instance_variable_get ivar
185
- else
186
- singleton_class.send name
187
- end
188
- end
189
- end
190
- end
191
- val
192
- end
193
-
194
- if instance_reader
195
- undef_method(name) if method_defined?(name) || private_method_defined?(name)
196
- define_method(name) do
197
- if instance_variable_defined?(ivar)
198
- instance_variable_get ivar
199
- else
200
- self.class.public_send name
201
- end
202
- end
203
- end
204
-
205
- if instance_writer
206
- m = "#{name}="
207
- undef_method(m) if method_defined?(m) || private_method_defined?(m)
208
- attr_writer name
209
- end
210
- end
211
- end
212
-
213
245
  end
214
246
  end
215
247
  end