sidekiq 4.2.10 → 5.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 (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/5.0-Upgrade.md +56 -0
  4. data/Changes.md +24 -1
  5. data/Ent-Changes.md +3 -2
  6. data/Pro-Changes.md +6 -2
  7. data/README.md +2 -2
  8. data/bin/sidekiqctl +1 -1
  9. data/bin/sidekiqload +3 -8
  10. data/lib/sidekiq/api.rb +33 -14
  11. data/lib/sidekiq/cli.rb +12 -5
  12. data/lib/sidekiq/client.rb +15 -13
  13. data/lib/sidekiq/delay.rb +21 -0
  14. data/lib/sidekiq/extensions/generic_proxy.rb +7 -1
  15. data/lib/sidekiq/job_logger.rb +27 -0
  16. data/lib/sidekiq/job_retry.rb +235 -0
  17. data/lib/sidekiq/launcher.rb +1 -7
  18. data/lib/sidekiq/middleware/server/active_record.rb +9 -0
  19. data/lib/sidekiq/processor.rb +68 -31
  20. data/lib/sidekiq/rails.rb +2 -65
  21. data/lib/sidekiq/redis_connection.rb +1 -1
  22. data/lib/sidekiq/testing.rb +1 -1
  23. data/lib/sidekiq/version.rb +1 -1
  24. data/lib/sidekiq/web/action.rb +0 -4
  25. data/lib/sidekiq/web/application.rb +6 -11
  26. data/lib/sidekiq/web/helpers.rb +9 -1
  27. data/lib/sidekiq/worker.rb +34 -11
  28. data/lib/sidekiq.rb +4 -13
  29. data/sidekiq.gemspec +1 -1
  30. data/web/assets/javascripts/dashboard.js +10 -12
  31. data/web/assets/stylesheets/application-rtl.css +246 -0
  32. data/web/assets/stylesheets/application.css +336 -4
  33. data/web/assets/stylesheets/bootstrap-rtl.min.css +9 -0
  34. data/web/locales/ar.yml +80 -0
  35. data/web/locales/fa.yml +1 -0
  36. data/web/locales/he.yml +79 -0
  37. data/web/locales/ur.yml +80 -0
  38. data/web/views/_footer.erb +1 -1
  39. data/web/views/_nav.erb +1 -1
  40. data/web/views/_paging.erb +1 -1
  41. data/web/views/busy.erb +4 -4
  42. data/web/views/dashboard.erb +1 -1
  43. data/web/views/layout.erb +10 -1
  44. data/web/views/morgue.erb +4 -4
  45. data/web/views/queue.erb +7 -7
  46. data/web/views/retries.erb +5 -5
  47. data/web/views/scheduled.erb +2 -2
  48. metadata +15 -8
  49. data/lib/sidekiq/middleware/server/logging.rb +0 -31
  50. data/lib/sidekiq/middleware/server/retry_jobs.rb +0 -205
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 595500a3810c25e8e04e86c644f966ff01cb035f
4
- data.tar.gz: 3f92a9f61e61848bc2c0639469ce3588f3848fc0
3
+ metadata.gz: f2a9cd7270e53981aaf7b3f2639596ff042f5ae3
4
+ data.tar.gz: 7b6e4fbfee794de34d9b6b15772cbf085e05a65b
5
5
  SHA512:
6
- metadata.gz: c4e97c3665d1e902f47cfb579fda437dc834ac4b584606f1ca3b8fd9225e8502cacf5fb687673b4735b359de6af179589759a34369f1c74e904b37f8fe70a4ee
7
- data.tar.gz: a4e6d41067bf6b88c77577def0c1f9ecc3f5d46f0bdfb0821952c26867e91a71c64231aab09a25096d22c3272dea2dcc37547bc6096dd7622a192fa00e0a4e50
6
+ metadata.gz: dfaecc27ce4071e36b5ab994c27f59d85b4cf7f16ca05a5b786c79125c311f58fbb38b94f7e1c71e4dbf90e6645cb358102e8940a94881981f7bbc2578fd18ff
7
+ data.tar.gz: a98e9b87e5f4abe2580ea5fcb6f20ef1d28623eae9be4ca758d5f5b52c65dbef7a6b5df74f673449177f36494b9075573315c7ef6cd6b757ba6a59e825737833
data/.gitignore CHANGED
@@ -10,3 +10,4 @@ vendor/
10
10
  .bundle/
11
11
  .sass-cache/
12
12
  tmp/
13
+ pkg/*.gem
data/5.0-Upgrade.md ADDED
@@ -0,0 +1,56 @@
1
+ # Welcome to Sidekiq 5.0!
2
+
3
+ Sidekiq 5.0 contains a reworked job dispatch and execution core to integrate
4
+ better with the new Rails 5.0 Executor. It also drops support for older
5
+ versions of Ruby and Rails and adds support for RTL languages in the Web UI.
6
+
7
+ ## What's New
8
+
9
+ * Integrate job logging and retry logic directly in with the job
10
+ execution logic in Sidekiq::Processor. Previously this logic was
11
+ defined as middleware. In Rails 5.0, ActiveSupport::Executor handles ActiveRecord
12
+ connection management, job callbacks, development mode class loading,
13
+ etc. Because of its extensive responsibilities, the Executor can't be
14
+ integrated as Sidekiq middleware; the logging/retry logic had to be pulled out
15
+ too. Sidekiq 4.2 had a hack to make it work but this redesign provides
16
+ a cleaner integration. [#3235]
17
+ * The Delayed Extensions `delay`, `delay_in` and `delay_until` APIs are
18
+ no longer available by default. The extensions allow you to marshal
19
+ job arguments as YAML, leading to cases where job payloads could be many
20
+ 100s of KB or larger if not careful, leading to Redis networking
21
+ timeouts or other problems. As noted in the Best Practices wiki page,
22
+ Sidekiq is designed for jobs with small, simple arguments.
23
+
24
+ Add this line to your initializer to re-enable them and get the old behavior:
25
+ ```ruby
26
+ Sidekiq::Extensions.enable_delay!
27
+ ```
28
+ The old `Sidekiq.remove_delay!` API has been removed as it is now the default. [#3299]
29
+ * Sidekiq's quiet signal is now `TSTP` (think of it as **T**hread
30
+ **ST**o**P**) instead of USR1 as USR1 is not available on JRuby.
31
+ USR1 will continue to be supported in Sidekiq 5.x for backwards
32
+ compatibility and will be removed in Sidekiq 6.x. [#3302]
33
+ * The Web UI is now bi-directional - it can render either LTR
34
+ (left-to-right) or RTL languages. With this change, **Farsi, Arabic,
35
+ Hebrew and Urdu** are officially supported. [#3381]
36
+ * Jobs which can't be parsed due to invalid JSON are now pushed
37
+ immediately to the Dead set since they require manual intervention and
38
+ will never execute successfully as is. The Web UI has been updated to
39
+ more gracefully display these jobs. [#3296]
40
+ * **Rails 3.2** is no longer supported.
41
+ * **Ruby 2.0 and Ruby 2.1** are no longer supported. Ruby 2.2.2+ is required.
42
+
43
+ ## Upgrade
44
+
45
+ As always, please upgrade Sidekiq **one major version at a time**.
46
+ If you are already running Sidekiq 4.x, then:
47
+
48
+ * Upgrade to the latest Sidekiq 4.x.
49
+ ```ruby
50
+ gem 'sidekiq', '< 5'
51
+ ```
52
+ * Fix any deprecation warnings you see.
53
+ * Upgrade to 5.x.
54
+ ```ruby
55
+ gem 'sidekiq', '< 6'
56
+ ```
data/Changes.md CHANGED
@@ -1,6 +1,29 @@
1
1
  # Sidekiq Changes
2
2
 
3
- HEAD
3
+ [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)
4
+
5
+ 5.0.0
6
+ -----------
7
+
8
+ - **BREAKING CHANGE** Job dispatch was refactored for safer integration with
9
+ Rails 5. The **Logging** and **RetryJobs** server middleware were removed and
10
+ functionality integrated directly into Sidekiq::Processor. These aren't
11
+ commonly used public APIs so this shouldn't impact most users.
12
+ ```
13
+ Sidekiq::Middleware::Server::RetryJobs -> Sidekiq::JobRetry
14
+ Sidekiq::Middleware::Server::Logging -> Sidekiq::JobLogging
15
+ ```
16
+ - Quieting Sidekiq is now done via the TSTP signal, the USR1 signal is deprecated.
17
+ - The `delay` extension APIs are no longer available by default, you
18
+ must opt into them.
19
+ - The Web UI is now BiDi and can render RTL languages like Arabic, Farsi and Hebrew.
20
+ - Rails 3.2 and Ruby 2.0 and 2.1 are no longer supported.
21
+ - The `SomeWorker.set(options)` API was re-written to avoid thread-local state. [#2152]
22
+ - Sidekiq Enterprise's encrypted jobs now display "[encrypted data]" in the Web UI instead
23
+ of random hex bytes.
24
+ - Please see the [5.0 Upgrade notes](5.0-Upgrade.md) for more detail.
25
+
26
+ 4.2.10
4
27
  -----------
5
28
 
6
29
  - Scheduled jobs can now be moved directly to the Dead queue via API [#3390]
data/Ent-Changes.md CHANGED
@@ -1,5 +1,6 @@
1
- Sidekiq Enterprise Changelog
2
- =======================
1
+ # Sidekiq Enterprise Changelog
2
+
3
+ [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)
3
4
 
4
5
  Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
5
6
 
data/Pro-Changes.md CHANGED
@@ -1,11 +1,15 @@
1
- Sidekiq Pro Changelog
2
- =======================
1
+ # Sidekiq Pro Changelog
2
+
3
+ [Sidekiq Changes](https://github.com/mperham/sidekiq/blob/master/Changes.md) | [Sidekiq Pro Changes](https://github.com/mperham/sidekiq/blob/master/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/mperham/sidekiq/blob/master/Ent-Changes.md)
3
4
 
4
5
  Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
5
6
 
6
7
  HEAD
7
8
  ---------
8
9
 
10
+ - Re-implement `Sidekiq::Queue#delete_job` to avoid O(n) runtime [#3408]
11
+ - Batch page displays Pending JIDs if less than 10 [#3130]
12
+ - Batch page has a Search button to find associated Retries [#3130]
9
13
  - Make Batch UI progress bar more friendly to the colorblind [#3387]
10
14
 
11
15
  3.4.5
data/README.md CHANGED
@@ -32,9 +32,9 @@ DelayedJob 4.1.1 | - | - | 465 sec | 215 jobs/sec
32
32
  Requirements
33
33
  -----------------
34
34
 
35
- Sidekiq supports CRuby 2.0+ and JRuby 9k.
35
+ Sidekiq supports CRuby 2.2.2+ and JRuby 9k.
36
36
 
37
- All Rails releases >= 3.2 are officially supported.
37
+ All Rails releases >= 4.0 are officially supported.
38
38
 
39
39
  Redis 2.8 or greater is required. 3.0.3+ is recommended for large
40
40
  installations with thousands of worker threads.
data/bin/sidekiqctl CHANGED
@@ -64,7 +64,7 @@ class Sidekiqctl
64
64
  end
65
65
 
66
66
  def quiet
67
- `kill -USR1 #{pid}`
67
+ `kill -TSTP #{pid}`
68
68
  end
69
69
 
70
70
  def stop
data/bin/sidekiqload CHANGED
@@ -46,7 +46,7 @@ end
46
46
  #}])
47
47
 
48
48
  self_read, self_write = IO.pipe
49
- %w(INT TERM USR1 USR2 TTIN).each do |sig|
49
+ %w(INT TERM TSTP TTIN).each do |sig|
50
50
  begin
51
51
  trap sig do
52
52
  self_write.puts(sig)
@@ -67,14 +67,9 @@ def handle_signal(launcher, sig)
67
67
  when 'TERM'
68
68
  # Heroku sends TERM and then waits 10 seconds for process to exit.
69
69
  raise Interrupt
70
- when 'USR1'
71
- Sidekiq.logger.info "Received USR1, no longer accepting new work"
70
+ when 'TSTP'
71
+ Sidekiq.logger.info "Received TSTP, no longer accepting new work"
72
72
  launcher.quiet
73
- when 'USR2'
74
- if Sidekiq.options[:logfile]
75
- Sidekiq.logger.info "Received USR2, reopening log file"
76
- Sidekiq::Logging.reopen_logs
77
- end
78
73
  when 'TTIN'
79
74
  Thread.list.each do |thread|
80
75
  Sidekiq.logger.warn "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
data/lib/sidekiq/api.rb CHANGED
@@ -75,7 +75,7 @@ module Sidekiq
75
75
  enqueued = pipe2_res[s..-1].map(&:to_i).inject(0, &:+)
76
76
 
77
77
  default_queue_latency = if (entry = pipe1_res[6].first)
78
- job = Sidekiq.load_json(entry)
78
+ job = Sidekiq.load_json(entry) rescue {}
79
79
  now = Time.now.to_f
80
80
  thence = job['enqueued_at'.freeze] || now
81
81
  now - thence
@@ -287,13 +287,25 @@ module Sidekiq
287
287
  attr_reader :value
288
288
 
289
289
  def initialize(item, queue_name=nil)
290
+ @args = nil
290
291
  @value = item
291
- @item = item.is_a?(Hash) ? item : Sidekiq.load_json(item)
292
+ @item = item.is_a?(Hash) ? item : parse(item)
292
293
  @queue = queue_name || @item['queue']
293
294
  end
294
295
 
296
+ def parse(item)
297
+ Sidekiq.load_json(item)
298
+ rescue JSON::ParserError
299
+ # If the job payload in Redis is invalid JSON, we'll load
300
+ # the item as an empty hash and store the invalid JSON as
301
+ # the job 'args' for display in the Web UI.
302
+ @invalid = true
303
+ @args = [item]
304
+ {}
305
+ end
306
+
295
307
  def klass
296
- @item['class']
308
+ self['class']
297
309
  end
298
310
 
299
311
  def display_class
@@ -324,32 +336,36 @@ module Sidekiq
324
336
  arg
325
337
  end
326
338
  when "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
327
- job_args = @item['wrapped'] ? args[0]["arguments"] : []
328
- if 'ActionMailer::DeliveryJob' == (@item['wrapped'] || args[0])
329
- # remove MailerClass, mailer_method and 'deliver_now'
330
- job_args.drop(3)
339
+ job_args = self['wrapped'] ? args[0]["arguments"] : []
340
+ if 'ActionMailer::DeliveryJob' == (self['wrapped'] || args[0])
341
+ # remove MailerClass, mailer_method and 'deliver_now'
342
+ job_args.drop(3)
331
343
  else
332
- job_args
344
+ job_args
333
345
  end
334
346
  else
347
+ if self['encrypt'.freeze]
348
+ # no point in showing 150+ bytes of random garbage
349
+ args[-1] = '[encrypted data]'.freeze
350
+ end
335
351
  args
336
352
  end
337
353
  end
338
354
 
339
355
  def args
340
- @item['args']
356
+ @args || @item['args']
341
357
  end
342
358
 
343
359
  def jid
344
- @item['jid']
360
+ self['jid']
345
361
  end
346
362
 
347
363
  def enqueued_at
348
- @item['enqueued_at'] ? Time.at(@item['enqueued_at']).utc : nil
364
+ self['enqueued_at'] ? Time.at(self['enqueued_at']).utc : nil
349
365
  end
350
366
 
351
367
  def created_at
352
- Time.at(@item['created_at'] || @item['enqueued_at'] || 0).utc
368
+ Time.at(self['created_at'] || self['enqueued_at'] || 0).utc
353
369
  end
354
370
 
355
371
  def queue
@@ -371,7 +387,10 @@ module Sidekiq
371
387
  end
372
388
 
373
389
  def [](name)
374
- @item[name]
390
+ # nil will happen if the JSON fails to parse.
391
+ # We don't guarantee Sidekiq will work with bad job JSON but we should
392
+ # make a best effort to minimize the damage.
393
+ @item ? @item[name] : nil
375
394
  end
376
395
 
377
396
  private
@@ -756,7 +775,7 @@ module Sidekiq
756
775
  end
757
776
 
758
777
  def quiet!
759
- signal('USR1')
778
+ signal('TSTP')
760
779
  end
761
780
 
762
781
  def stop!
data/lib/sidekiq/cli.rb CHANGED
@@ -43,6 +43,10 @@ module Sidekiq
43
43
  write_pid
44
44
  end
45
45
 
46
+ def jruby?
47
+ defined?(::JRUBY_VERSION)
48
+ end
49
+
46
50
  # Code within this method is not tested because it alters
47
51
  # global process state irreversibly. PRs which improve the
48
52
  # test coverage of Sidekiq::CLI are welcomed.
@@ -51,8 +55,14 @@ module Sidekiq
51
55
  print_banner
52
56
 
53
57
  self_read, self_write = IO.pipe
58
+ sigs = %w(INT TERM TTIN TSTP)
59
+ # USR1 and USR2 don't work on the JVM
60
+ if !jruby?
61
+ sigs << 'USR1'
62
+ sigs << 'USR2'
63
+ end
54
64
 
55
- %w(INT TERM USR1 USR2 TTIN TSTP).each do |sig|
65
+ sigs.each do |sig|
56
66
  begin
57
67
  trap sig do
58
68
  self_write.puts(sig)
@@ -230,9 +240,7 @@ module Sidekiq
230
240
  if File.directory?(options[:require])
231
241
  require 'rails'
232
242
  if ::Rails::VERSION::MAJOR < 4
233
- require 'sidekiq/rails'
234
- require File.expand_path("#{options[:require]}/config/environment.rb")
235
- ::Rails.application.eager_load!
243
+ raise "Sidekiq no longer supports this version of Rails"
236
244
  elsif ::Rails::VERSION::MAJOR == 4
237
245
  # Painful contortions, see 1791 for discussion
238
246
  # No autoloading, we want to force eager load for everything.
@@ -243,7 +251,6 @@ module Sidekiq
243
251
  require 'sidekiq/rails'
244
252
  require File.expand_path("#{options[:require]}/config/environment.rb")
245
253
  else
246
- # Rails 5+ && development mode, use Reloader
247
254
  require 'sidekiq/rails'
248
255
  require File.expand_path("#{options[:require]}/config/environment.rb")
249
256
  end
@@ -48,6 +48,7 @@ module Sidekiq
48
48
  # queue - the named queue to use, default 'default'
49
49
  # class - the worker class to call, required
50
50
  # args - an array of simple arguments to the perform method, must be JSON-serializable
51
+ # at - timestamp to schedule the job (optional), must be Numeric (e.g. Time.now.to_f)
51
52
  # retry - whether to retry this job if it fails, default true or an integer number of retries
52
53
  # backtrace - whether to save any error backtrace, default false
53
54
  #
@@ -62,11 +63,11 @@ module Sidekiq
62
63
  #
63
64
  def push(item)
64
65
  normed = normalize_item(item)
65
- payload = process_single(item['class'], normed)
66
+ payload = process_single(item['class'.freeze], normed)
66
67
 
67
68
  if payload
68
69
  raw_push([payload])
69
- payload['jid']
70
+ payload['jid'.freeze]
70
71
  end
71
72
  end
72
73
 
@@ -83,19 +84,19 @@ module Sidekiq
83
84
  # Returns an array of the of pushed jobs' jids. The number of jobs pushed can be less
84
85
  # than the number given if the middleware stopped processing for one or more jobs.
85
86
  def push_bulk(items)
86
- arg = items['args'].first
87
+ arg = items['args'.freeze].first
87
88
  return [] unless arg # no jobs to push
88
89
  raise ArgumentError, "Bulk arguments must be an Array of Arrays: [[1], [2]]" if !arg.is_a?(Array)
89
90
 
90
91
  normed = normalize_item(items)
91
- payloads = items['args'].map do |args|
92
- copy = normed.merge('args' => args, 'jid' => SecureRandom.hex(12), 'enqueued_at' => Time.now.to_f)
93
- result = process_single(items['class'], copy)
92
+ payloads = items['args'.freeze].map do |args|
93
+ copy = normed.merge('args'.freeze => args, 'jid'.freeze => SecureRandom.hex(12), 'enqueued_at'.freeze => Time.now.to_f)
94
+ result = process_single(items['class'.freeze], copy)
94
95
  result ? result : nil
95
96
  end.compact
96
97
 
97
98
  raw_push(payloads) if !payloads.empty?
98
- payloads.collect { |payload| payload['jid'] }
99
+ payloads.collect { |payload| payload['jid'.freeze] }
99
100
  end
100
101
 
101
102
  # Allows sharding of jobs across any number of Redis instances. All jobs
@@ -139,14 +140,14 @@ module Sidekiq
139
140
  # Messages are enqueued to the 'default' queue.
140
141
  #
141
142
  def enqueue(klass, *args)
142
- klass.client_push('class' => klass, 'args' => args)
143
+ klass.client_push('class'.freeze => klass, 'args'.freeze => args)
143
144
  end
144
145
 
145
146
  # Example usage:
146
147
  # Sidekiq::Client.enqueue_to(:queue_name, MyWorker, 'foo', 1, :bat => 'bar')
147
148
  #
148
149
  def enqueue_to(queue, klass, *args)
149
- klass.client_push('queue' => queue, 'class' => klass, 'args' => args)
150
+ klass.client_push('queue'.freeze => queue, 'class'.freeze => klass, 'args'.freeze => args)
150
151
  end
151
152
 
152
153
  # Example usage:
@@ -157,7 +158,7 @@ module Sidekiq
157
158
  now = Time.now.to_f
158
159
  ts = (int < 1_000_000_000 ? now + int : int)
159
160
 
160
- item = { 'class' => klass, 'args' => args, 'at' => ts, 'queue' => queue }
161
+ item = { 'class'.freeze => klass, 'args'.freeze => args, 'at'.freeze => ts, 'queue'.freeze => queue }
161
162
  item.delete('at'.freeze) if ts <= now
162
163
 
163
164
  klass.client_push(item)
@@ -183,13 +184,13 @@ module Sidekiq
183
184
  end
184
185
 
185
186
  def atomic_push(conn, payloads)
186
- if payloads.first['at']
187
+ if payloads.first['at'.freeze]
187
188
  conn.zadd('schedule'.freeze, payloads.map do |hash|
188
189
  at = hash.delete('at'.freeze).to_s
189
190
  [at, Sidekiq.dump_json(hash)]
190
191
  end)
191
192
  else
192
- q = payloads.first['queue']
193
+ q = payloads.first['queue'.freeze]
193
194
  now = Time.now.to_f
194
195
  to_push = payloads.map do |entry|
195
196
  entry['enqueued_at'.freeze] = now
@@ -201,7 +202,7 @@ module Sidekiq
201
202
  end
202
203
 
203
204
  def process_single(worker_class, item)
204
- queue = item['queue']
205
+ queue = item['queue'.freeze]
205
206
 
206
207
  middleware.invoke(worker_class, item, queue, @redis_pool) do
207
208
  item
@@ -212,6 +213,7 @@ module Sidekiq
212
213
  raise(ArgumentError, "Job must be a Hash with 'class' and 'args' keys: { 'class' => SomeWorker, 'args' => ['bob', 1, :foo => 'bar'] }") unless item.is_a?(Hash) && item.has_key?('class'.freeze) && item.has_key?('args'.freeze)
213
214
  raise(ArgumentError, "Job args must be an Array") unless item['args'].is_a?(Array)
214
215
  raise(ArgumentError, "Job class must be either a Class or String representation of the class name") unless item['class'.freeze].is_a?(Class) || item['class'.freeze].is_a?(String)
216
+ raise(ArgumentError, "Job 'at' must be a Numeric timestamp") if item.has_key?('at'.freeze) && !item['at'].is_a?(Numeric)
215
217
  #raise(ArgumentError, "Arguments must be native JSON types, see https://github.com/mperham/sidekiq/wiki/Best-Practices") unless JSON.load(JSON.dump(item['args'])) == item['args']
216
218
 
217
219
  normalized_hash(item['class'.freeze])
@@ -0,0 +1,21 @@
1
+ module Sidekiq
2
+ module Extensions
3
+
4
+ def self.enable_delay!
5
+ if defined?(::ActiveSupport)
6
+ ActiveSupport.on_load(:active_record) do
7
+ require 'sidekiq/extensions/active_record'
8
+ include Sidekiq::Extensions::ActiveRecord
9
+ end
10
+ ActiveSupport.on_load(:action_mailer) do
11
+ require 'sidekiq/extensions/action_mailer'
12
+ extend Sidekiq::Extensions::ActionMailer
13
+ end
14
+ end
15
+
16
+ require 'sidekiq/extensions/class_methods'
17
+ Module.__send__(:include, Sidekiq::Extensions::Klass)
18
+ end
19
+
20
+ end
21
+ end
@@ -3,6 +3,8 @@ require 'yaml'
3
3
 
4
4
  module Sidekiq
5
5
  module Extensions
6
+ SIZE_LIMIT = 8_192
7
+
6
8
  class Proxy < BasicObject
7
9
  def initialize(performable, target, options={})
8
10
  @performable = performable
@@ -17,7 +19,11 @@ module Sidekiq
17
19
  # to JSON and then deserialized on the other side back into a
18
20
  # Ruby object.
19
21
  obj = [@target, name, args]
20
- @performable.client_push({ 'class' => @performable, 'args' => [::YAML.dump(obj)] }.merge(@opts))
22
+ marshalled = ::YAML.dump(obj)
23
+ if marshalled.size > SIZE_LIMIT
24
+ ::Sidekiq.logger.warn { "#{@target}.#{name} job argument is #{marshalled.bytesize} bytes, you should refactor it to reduce the size" }
25
+ end
26
+ @performable.client_push({ 'class' => @performable, 'args' => [marshalled] }.merge(@opts))
21
27
  end
22
28
  end
23
29
 
@@ -0,0 +1,27 @@
1
+ module Sidekiq
2
+ class JobLogger
3
+
4
+ def call(item, queue)
5
+ begin
6
+ start = Time.now
7
+ logger.info("start".freeze)
8
+ yield
9
+ logger.info("done: #{elapsed(start)} sec")
10
+ rescue Exception
11
+ logger.info("fail: #{elapsed(start)} sec")
12
+ raise
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def elapsed(start)
19
+ (Time.now - start).round(3)
20
+ end
21
+
22
+ def logger
23
+ Sidekiq.logger
24
+ end
25
+ end
26
+ end
27
+