sidekiq 4.1.4 → 6.5.6

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 (213) hide show
  1. checksums.yaml +5 -5
  2. data/Changes.md +666 -0
  3. data/LICENSE +3 -3
  4. data/README.md +27 -35
  5. data/bin/sidekiq +27 -3
  6. data/bin/sidekiqload +78 -84
  7. data/bin/sidekiqmon +8 -0
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/job_spec.rb.erb +6 -0
  11. data/lib/generators/sidekiq/templates/job_test.rb.erb +8 -0
  12. data/lib/sidekiq/api.rb +583 -288
  13. data/lib/sidekiq/cli.rb +255 -218
  14. data/lib/sidekiq/client.rb +86 -83
  15. data/lib/sidekiq/component.rb +65 -0
  16. data/lib/sidekiq/delay.rb +43 -0
  17. data/lib/sidekiq/extensions/action_mailer.rb +13 -22
  18. data/lib/sidekiq/extensions/active_record.rb +13 -10
  19. data/lib/sidekiq/extensions/class_methods.rb +14 -11
  20. data/lib/sidekiq/extensions/generic_proxy.rb +13 -5
  21. data/lib/sidekiq/fetch.rb +50 -40
  22. data/lib/sidekiq/job.rb +13 -0
  23. data/lib/sidekiq/job_logger.rb +51 -0
  24. data/lib/sidekiq/job_retry.rb +282 -0
  25. data/lib/sidekiq/job_util.rb +71 -0
  26. data/lib/sidekiq/launcher.rb +192 -85
  27. data/lib/sidekiq/logger.rb +156 -0
  28. data/lib/sidekiq/manager.rb +44 -45
  29. data/lib/sidekiq/metrics/deploy.rb +47 -0
  30. data/lib/sidekiq/metrics/query.rb +153 -0
  31. data/lib/sidekiq/metrics/shared.rb +94 -0
  32. data/lib/sidekiq/metrics/tracking.rb +134 -0
  33. data/lib/sidekiq/middleware/chain.rb +102 -46
  34. data/lib/sidekiq/middleware/current_attributes.rb +63 -0
  35. data/lib/sidekiq/middleware/i18n.rb +7 -7
  36. data/lib/sidekiq/middleware/modules.rb +21 -0
  37. data/lib/sidekiq/monitor.rb +133 -0
  38. data/lib/sidekiq/paginator.rb +20 -16
  39. data/lib/sidekiq/processor.rb +178 -78
  40. data/lib/sidekiq/rails.rb +56 -27
  41. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  42. data/lib/sidekiq/redis_connection.rb +123 -47
  43. data/lib/sidekiq/ring_buffer.rb +29 -0
  44. data/lib/sidekiq/scheduled.rb +97 -40
  45. data/lib/sidekiq/sd_notify.rb +149 -0
  46. data/lib/sidekiq/systemd.rb +24 -0
  47. data/lib/sidekiq/testing/inline.rb +6 -5
  48. data/lib/sidekiq/testing.rb +83 -56
  49. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  50. data/lib/sidekiq/version.rb +2 -1
  51. data/lib/sidekiq/web/action.rb +93 -0
  52. data/lib/sidekiq/web/application.rb +379 -0
  53. data/lib/sidekiq/web/csrf_protection.rb +180 -0
  54. data/lib/sidekiq/web/helpers.rb +365 -0
  55. data/lib/sidekiq/web/router.rb +104 -0
  56. data/lib/sidekiq/web.rb +108 -213
  57. data/lib/sidekiq/worker.rb +288 -42
  58. data/lib/sidekiq.rb +188 -80
  59. data/sidekiq.gemspec +24 -22
  60. data/web/assets/images/apple-touch-icon.png +0 -0
  61. data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
  62. data/web/assets/javascripts/application.js +130 -75
  63. data/web/assets/javascripts/chart.min.js +13 -0
  64. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  65. data/web/assets/javascripts/dashboard.js +70 -91
  66. data/web/assets/javascripts/graph.js +16 -0
  67. data/web/assets/javascripts/metrics.js +262 -0
  68. data/web/assets/stylesheets/application-dark.css +143 -0
  69. data/web/assets/stylesheets/application-rtl.css +242 -0
  70. data/web/assets/stylesheets/application.css +390 -145
  71. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  72. data/web/assets/stylesheets/bootstrap.css +4 -8
  73. data/web/locales/ar.yml +87 -0
  74. data/web/locales/de.yml +15 -3
  75. data/web/locales/el.yml +43 -19
  76. data/web/locales/en.yml +15 -1
  77. data/web/locales/es.yml +22 -5
  78. data/web/locales/fa.yml +80 -0
  79. data/web/locales/fr.yml +10 -3
  80. data/web/locales/he.yml +79 -0
  81. data/web/locales/ja.yml +12 -4
  82. data/web/locales/lt.yml +83 -0
  83. data/web/locales/pl.yml +4 -4
  84. data/web/locales/pt-br.yml +27 -9
  85. data/web/locales/ru.yml +4 -0
  86. data/web/locales/ur.yml +80 -0
  87. data/web/locales/vi.yml +83 -0
  88. data/web/views/_footer.erb +6 -3
  89. data/web/views/_job_info.erb +4 -3
  90. data/web/views/_nav.erb +5 -19
  91. data/web/views/_paging.erb +1 -1
  92. data/web/views/_poll_link.erb +2 -5
  93. data/web/views/_summary.erb +7 -7
  94. data/web/views/busy.erb +64 -26
  95. data/web/views/dashboard.erb +26 -17
  96. data/web/views/dead.erb +4 -4
  97. data/web/views/layout.erb +15 -5
  98. data/web/views/metrics.erb +69 -0
  99. data/web/views/metrics_for_job.erb +87 -0
  100. data/web/views/morgue.erb +21 -14
  101. data/web/views/queue.erb +28 -14
  102. data/web/views/queues.erb +15 -5
  103. data/web/views/retries.erb +24 -15
  104. data/web/views/retry.erb +5 -5
  105. data/web/views/scheduled.erb +9 -6
  106. data/web/views/scheduled_job_info.erb +1 -1
  107. metadata +73 -256
  108. data/.github/contributing.md +0 -32
  109. data/.github/issue_template.md +0 -4
  110. data/.gitignore +0 -12
  111. data/.travis.yml +0 -18
  112. data/3.0-Upgrade.md +0 -70
  113. data/4.0-Upgrade.md +0 -53
  114. data/COMM-LICENSE +0 -95
  115. data/Ent-Changes.md +0 -123
  116. data/Gemfile +0 -29
  117. data/Pro-2.0-Upgrade.md +0 -138
  118. data/Pro-3.0-Upgrade.md +0 -44
  119. data/Pro-Changes.md +0 -559
  120. data/Rakefile +0 -9
  121. data/bin/sidekiqctl +0 -99
  122. data/code_of_conduct.md +0 -50
  123. data/lib/generators/sidekiq/templates/worker_spec.rb.erb +0 -6
  124. data/lib/generators/sidekiq/templates/worker_test.rb.erb +0 -8
  125. data/lib/generators/sidekiq/worker_generator.rb +0 -49
  126. data/lib/sidekiq/core_ext.rb +0 -106
  127. data/lib/sidekiq/exception_handler.rb +0 -31
  128. data/lib/sidekiq/logging.rb +0 -106
  129. data/lib/sidekiq/middleware/server/active_record.rb +0 -13
  130. data/lib/sidekiq/middleware/server/logging.rb +0 -40
  131. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
  132. data/lib/sidekiq/util.rb +0 -62
  133. data/lib/sidekiq/web_helpers.rb +0 -255
  134. data/test/config.yml +0 -9
  135. data/test/env_based_config.yml +0 -11
  136. data/test/fake_env.rb +0 -1
  137. data/test/fixtures/en.yml +0 -2
  138. data/test/helper.rb +0 -75
  139. data/test/test_actors.rb +0 -138
  140. data/test/test_api.rb +0 -528
  141. data/test/test_cli.rb +0 -406
  142. data/test/test_client.rb +0 -266
  143. data/test/test_exception_handler.rb +0 -56
  144. data/test/test_extensions.rb +0 -127
  145. data/test/test_fetch.rb +0 -50
  146. data/test/test_launcher.rb +0 -85
  147. data/test/test_logging.rb +0 -35
  148. data/test/test_manager.rb +0 -50
  149. data/test/test_middleware.rb +0 -158
  150. data/test/test_processor.rb +0 -201
  151. data/test/test_rails.rb +0 -22
  152. data/test/test_redis_connection.rb +0 -132
  153. data/test/test_retry.rb +0 -326
  154. data/test/test_retry_exhausted.rb +0 -149
  155. data/test/test_scheduled.rb +0 -115
  156. data/test/test_scheduling.rb +0 -50
  157. data/test/test_sidekiq.rb +0 -107
  158. data/test/test_testing.rb +0 -143
  159. data/test/test_testing_fake.rb +0 -357
  160. data/test/test_testing_inline.rb +0 -94
  161. data/test/test_util.rb +0 -13
  162. data/test/test_web.rb +0 -614
  163. data/test/test_web_helpers.rb +0 -54
  164. data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
  165. data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
  166. data/web/assets/images/status/active.png +0 -0
  167. data/web/assets/images/status/idle.png +0 -0
  168. data/web/assets/javascripts/locales/README.md +0 -27
  169. data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
  170. data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
  171. data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
  172. data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
  173. data/web/assets/javascripts/locales/jquery.timeago.cs.js +0 -18
  174. data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
  175. data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
  176. data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
  177. data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
  178. data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
  179. data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
  180. data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
  181. data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
  182. data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
  183. data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
  184. data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
  185. data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
  186. data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
  187. data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
  188. data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
  189. data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
  190. data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
  191. data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
  192. data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
  193. data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
  194. data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
  195. data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
  196. data/web/assets/javascripts/locales/jquery.timeago.nb.js +0 -18
  197. data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
  198. data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
  199. data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
  200. data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
  201. data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
  202. data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
  203. data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
  204. data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
  205. data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
  206. data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
  207. data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
  208. data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
  209. data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
  210. data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
  211. data/web/assets/javascripts/locales/jquery.timeago.zh-cn.js +0 -20
  212. data/web/assets/javascripts/locales/jquery.timeago.zh-tw.js +0 -20
  213. data/web/views/_poll_js.erb +0 -5
@@ -1,44 +1,270 @@
1
1
  # frozen_string_literal: true
2
- require 'sidekiq/client'
3
- require 'sidekiq/core_ext'
4
2
 
5
- module Sidekiq
3
+ require "sidekiq/client"
6
4
 
5
+ module Sidekiq
7
6
  ##
8
7
  # Include this module in your worker class and you can easily create
9
8
  # asynchronous jobs:
10
9
  #
11
- # class HardWorker
12
- # include Sidekiq::Worker
10
+ # class HardWorker
11
+ # include Sidekiq::Worker
12
+ # sidekiq_options queue: 'critical', retry: 5
13
13
  #
14
- # def perform(*args)
15
- # # do some work
14
+ # def perform(*args)
15
+ # # do some work
16
+ # end
16
17
  # end
17
- # end
18
18
  #
19
19
  # Then in your Rails app, you can do this:
20
20
  #
21
21
  # HardWorker.perform_async(1, 2, 3)
22
22
  #
23
23
  # Note that perform_async is a class method, perform is an instance method.
24
+ #
25
+ # Sidekiq::Worker also includes several APIs to provide compatibility with
26
+ # ActiveJob.
27
+ #
28
+ # class SomeWorker
29
+ # include Sidekiq::Worker
30
+ # queue_as :critical
31
+ #
32
+ # def perform(...)
33
+ # end
34
+ # end
35
+ #
36
+ # SomeWorker.set(wait_until: 1.hour).perform_async(123)
37
+ #
38
+ # Note that arguments passed to the job must still obey Sidekiq's
39
+ # best practice for simple, JSON-native data types. Sidekiq will not
40
+ # implement ActiveJob's more complex argument serialization. For
41
+ # this reason, we don't implement `perform_later` as our call semantics
42
+ # are very different.
43
+ #
24
44
  module Worker
45
+ ##
46
+ # The Options module is extracted so we can include it in ActiveJob::Base
47
+ # and allow native AJs to configure Sidekiq features/internals.
48
+ module Options
49
+ def self.included(base)
50
+ base.extend(ClassMethods)
51
+ base.sidekiq_class_attribute :sidekiq_options_hash
52
+ base.sidekiq_class_attribute :sidekiq_retry_in_block
53
+ base.sidekiq_class_attribute :sidekiq_retries_exhausted_block
54
+ end
55
+
56
+ module ClassMethods
57
+ ACCESSOR_MUTEX = Mutex.new
58
+
59
+ ##
60
+ # Allows customization for this type of Worker.
61
+ # Legal options:
62
+ #
63
+ # queue - name of queue to use for this job type, default *default*
64
+ # retry - enable retries for this Worker in case of error during execution,
65
+ # *true* to use the default or *Integer* count
66
+ # backtrace - whether to save any error backtrace in the retry payload to display in web UI,
67
+ # can be true, false or an integer number of lines to save, default *false*
68
+ #
69
+ # In practice, any option is allowed. This is the main mechanism to configure the
70
+ # options for a specific job.
71
+ def sidekiq_options(opts = {})
72
+ opts = opts.transform_keys(&:to_s) # stringify
73
+ self.sidekiq_options_hash = get_sidekiq_options.merge(opts)
74
+ end
75
+
76
+ def sidekiq_retry_in(&block)
77
+ self.sidekiq_retry_in_block = block
78
+ end
79
+
80
+ def sidekiq_retries_exhausted(&block)
81
+ self.sidekiq_retries_exhausted_block = block
82
+ end
83
+
84
+ def get_sidekiq_options # :nodoc:
85
+ self.sidekiq_options_hash ||= Sidekiq.default_job_options
86
+ end
87
+
88
+ def sidekiq_class_attribute(*attrs)
89
+ instance_reader = true
90
+ instance_writer = true
91
+
92
+ attrs.each do |name|
93
+ synchronized_getter = "__synchronized_#{name}"
94
+
95
+ singleton_class.instance_eval do
96
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
97
+ end
98
+
99
+ define_singleton_method(synchronized_getter) { nil }
100
+ singleton_class.class_eval do
101
+ private(synchronized_getter)
102
+ end
103
+
104
+ define_singleton_method(name) { ACCESSOR_MUTEX.synchronize { send synchronized_getter } }
105
+
106
+ ivar = "@#{name}"
107
+
108
+ singleton_class.instance_eval do
109
+ m = "#{name}="
110
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
111
+ end
112
+ define_singleton_method("#{name}=") do |val|
113
+ singleton_class.class_eval do
114
+ ACCESSOR_MUTEX.synchronize do
115
+ undef_method(synchronized_getter) if method_defined?(synchronized_getter) || private_method_defined?(synchronized_getter)
116
+ define_method(synchronized_getter) { val }
117
+ end
118
+ end
119
+
120
+ if singleton_class?
121
+ class_eval do
122
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
123
+ define_method(name) do
124
+ if instance_variable_defined? ivar
125
+ instance_variable_get ivar
126
+ else
127
+ singleton_class.send name
128
+ end
129
+ end
130
+ end
131
+ end
132
+ val
133
+ end
134
+
135
+ if instance_reader
136
+ undef_method(name) if method_defined?(name) || private_method_defined?(name)
137
+ define_method(name) do
138
+ if instance_variable_defined?(ivar)
139
+ instance_variable_get ivar
140
+ else
141
+ self.class.public_send name
142
+ end
143
+ end
144
+ end
145
+
146
+ if instance_writer
147
+ m = "#{name}="
148
+ undef_method(m) if method_defined?(m) || private_method_defined?(m)
149
+ attr_writer name
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+
25
156
  attr_accessor :jid
26
157
 
27
158
  def self.included(base)
28
- raise ArgumentError, "You cannot include Sidekiq::Worker in an ActiveJob: #{base.name}" if base.ancestors.any? {|c| c.name == 'ActiveJob::Base' }
159
+ raise ArgumentError, "Sidekiq::Worker cannot be included in an ActiveJob: #{base.name}" if base.ancestors.any? { |c| c.name == "ActiveJob::Base" }
29
160
 
161
+ base.include(Options)
30
162
  base.extend(ClassMethods)
31
- base.class_attribute :sidekiq_options_hash
32
- base.class_attribute :sidekiq_retry_in_block
33
- base.class_attribute :sidekiq_retries_exhausted_block
34
163
  end
35
164
 
36
165
  def logger
37
166
  Sidekiq.logger
38
167
  end
39
168
 
40
- module ClassMethods
169
+ # This helper class encapsulates the set options for `set`, e.g.
170
+ #
171
+ # SomeWorker.set(queue: 'foo').perform_async(....)
172
+ #
173
+ class Setter
174
+ include Sidekiq::JobUtil
175
+
176
+ def initialize(klass, opts)
177
+ @klass = klass
178
+ # NB: the internal hash always has stringified keys
179
+ @opts = opts.transform_keys(&:to_s)
180
+
181
+ # ActiveJob compatibility
182
+ interval = @opts.delete("wait_until") || @opts.delete("wait")
183
+ at(interval) if interval
184
+ end
41
185
 
186
+ def set(options)
187
+ hash = options.transform_keys(&:to_s)
188
+ interval = hash.delete("wait_until") || @opts.delete("wait")
189
+ @opts.merge!(hash)
190
+ at(interval) if interval
191
+ self
192
+ end
193
+
194
+ def perform_async(*args)
195
+ if @opts["sync"] == true
196
+ perform_inline(*args)
197
+ else
198
+ @klass.client_push(@opts.merge("args" => args, "class" => @klass))
199
+ end
200
+ end
201
+
202
+ # Explicit inline execution of a job. Returns nil if the job did not
203
+ # execute, true otherwise.
204
+ def perform_inline(*args)
205
+ raw = @opts.merge("args" => args, "class" => @klass)
206
+
207
+ # validate and normalize payload
208
+ item = normalize_item(raw)
209
+ queue = item["queue"]
210
+
211
+ # run client-side middleware
212
+ result = Sidekiq.client_middleware.invoke(item["class"], item, queue, Sidekiq.redis_pool) do
213
+ item
214
+ end
215
+ return nil unless result
216
+
217
+ # round-trip the payload via JSON
218
+ msg = Sidekiq.load_json(Sidekiq.dump_json(item))
219
+
220
+ # prepare the job instance
221
+ klass = msg["class"].constantize
222
+ job = klass.new
223
+ job.jid = msg["jid"]
224
+ job.bid = msg["bid"] if job.respond_to?(:bid)
225
+
226
+ # run the job through server-side middleware
227
+ result = Sidekiq.server_middleware.invoke(job, msg, msg["queue"]) do
228
+ # perform it
229
+ job.perform(*msg["args"])
230
+ true
231
+ end
232
+ return nil unless result
233
+ # jobs do not return a result. they should store any
234
+ # modified state.
235
+ true
236
+ end
237
+ alias_method :perform_sync, :perform_inline
238
+
239
+ def perform_bulk(args, batch_size: 1_000)
240
+ client = @klass.build_client
241
+ result = args.each_slice(batch_size).flat_map do |slice|
242
+ client.push_bulk(@opts.merge("class" => @klass, "args" => slice))
243
+ end
244
+
245
+ result.is_a?(Enumerator::Lazy) ? result.force : result
246
+ end
247
+
248
+ # +interval+ must be a timestamp, numeric or something that acts
249
+ # numeric (like an activesupport time interval).
250
+ def perform_in(interval, *args)
251
+ at(interval).perform_async(*args)
252
+ end
253
+ alias_method :perform_at, :perform_in
254
+
255
+ private
256
+
257
+ def at(interval)
258
+ int = interval.to_f
259
+ now = Time.now.to_f
260
+ ts = (int < 1_000_000_000 ? now + int : int)
261
+ # Optimization to enqueue something now that is scheduled to go out now or in the past
262
+ @opts["at"] = ts if ts > now
263
+ self
264
+ end
265
+ end
266
+
267
+ module ClassMethods
42
268
  def delay(*args)
43
269
  raise ArgumentError, "Do not call .delay on a Sidekiq::Worker class, call .perform_async"
44
270
  end
@@ -51,26 +277,59 @@ module Sidekiq
51
277
  raise ArgumentError, "Do not call .delay_until on a Sidekiq::Worker class, call .perform_at"
52
278
  end
53
279
 
280
+ def queue_as(q)
281
+ sidekiq_options("queue" => q.to_s)
282
+ end
283
+
54
284
  def set(options)
55
- Thread.current[:sidekiq_worker_set] = options
56
- self
285
+ Setter.new(self, options)
57
286
  end
58
287
 
59
288
  def perform_async(*args)
60
- client_push('class' => self, 'args' => args)
289
+ Setter.new(self, {}).perform_async(*args)
290
+ end
291
+
292
+ # Inline execution of job's perform method after passing through Sidekiq.client_middleware and Sidekiq.server_middleware
293
+ def perform_inline(*args)
294
+ Setter.new(self, {}).perform_inline(*args)
295
+ end
296
+ alias_method :perform_sync, :perform_inline
297
+
298
+ ##
299
+ # Push a large number of jobs to Redis, while limiting the batch of
300
+ # each job payload to 1,000. This method helps cut down on the number
301
+ # of round trips to Redis, which can increase the performance of enqueueing
302
+ # large numbers of jobs.
303
+ #
304
+ # +items+ must be an Array of Arrays.
305
+ #
306
+ # For finer-grained control, use `Sidekiq::Client.push_bulk` directly.
307
+ #
308
+ # Example (3 Redis round trips):
309
+ #
310
+ # SomeWorker.perform_async(1)
311
+ # SomeWorker.perform_async(2)
312
+ # SomeWorker.perform_async(3)
313
+ #
314
+ # Would instead become (1 Redis round trip):
315
+ #
316
+ # SomeWorker.perform_bulk([[1], [2], [3]])
317
+ #
318
+ def perform_bulk(*args, **kwargs)
319
+ Setter.new(self, {}).perform_bulk(*args, **kwargs)
61
320
  end
62
321
 
63
322
  # +interval+ must be a timestamp, numeric or something that acts
64
323
  # numeric (like an activesupport time interval).
65
324
  def perform_in(interval, *args)
66
325
  int = interval.to_f
67
- now = Time.now
68
- ts = (int < 1_000_000_000 ? (now + interval).to_f : int)
326
+ now = Time.now.to_f
327
+ ts = (int < 1_000_000_000 ? now + int : int)
69
328
 
70
- item = { 'class' => self, 'args' => args, 'at' => ts }
329
+ item = {"class" => self, "args" => args}
71
330
 
72
331
  # Optimization to enqueue something now that is scheduled to go out now or in the past
73
- item.delete('at'.freeze) if ts <= now.to_f
332
+ item["at"] = ts if ts > now
74
333
 
75
334
  client_push(item)
76
335
  end
@@ -89,33 +348,20 @@ module Sidekiq
89
348
  #
90
349
  # In practice, any option is allowed. This is the main mechanism to configure the
91
350
  # options for a specific job.
92
- def sidekiq_options(opts={})
93
- self.sidekiq_options_hash = get_sidekiq_options.merge(opts.stringify_keys)
94
- end
95
-
96
- def sidekiq_retry_in(&block)
97
- self.sidekiq_retry_in_block = block
98
- end
99
-
100
- def sidekiq_retries_exhausted(&block)
101
- self.sidekiq_retries_exhausted_block = block
102
- end
103
-
104
- def get_sidekiq_options # :nodoc:
105
- self.sidekiq_options_hash ||= Sidekiq.default_worker_options
351
+ def sidekiq_options(opts = {})
352
+ super
106
353
  end
107
354
 
108
355
  def client_push(item) # :nodoc:
109
- pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options['pool'] || Sidekiq.redis_pool
110
- hash = if Thread.current[:sidekiq_worker_set]
111
- x, Thread.current[:sidekiq_worker_set] = Thread.current[:sidekiq_worker_set], nil
112
- x.stringify_keys.merge(item.stringify_keys)
113
- else
114
- item.stringify_keys
115
- end
116
- Sidekiq::Client.new(pool).push(hash)
356
+ raise ArgumentError, "Job payloads should contain no Symbols: #{item}" if item.any? { |k, v| k.is_a?(::Symbol) }
357
+ build_client.push(item)
117
358
  end
118
359
 
360
+ def build_client # :nodoc:
361
+ pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
362
+ client_class = get_sidekiq_options["client_class"] || Sidekiq::Client
363
+ client_class.new(pool)
364
+ end
119
365
  end
120
366
  end
121
367
  end