sidekiq 6.0.3 → 6.1.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +13 -24
- data/6.0-Upgrade.md +1 -1
- data/Changes.md +61 -0
- data/Ent-Changes.md +15 -2
- data/Gemfile +2 -2
- data/Gemfile.lock +121 -109
- data/Pro-Changes.md +15 -1
- data/README.md +2 -5
- data/bin/sidekiq +26 -2
- data/lib/generators/sidekiq/worker_generator.rb +1 -1
- data/lib/sidekiq.rb +13 -7
- data/lib/sidekiq/api.rb +9 -5
- data/lib/sidekiq/cli.rb +24 -5
- data/lib/sidekiq/client.rb +23 -12
- data/lib/sidekiq/extensions/active_record.rb +3 -2
- data/lib/sidekiq/extensions/class_methods.rb +5 -4
- data/lib/sidekiq/fetch.rb +20 -18
- data/lib/sidekiq/job_logger.rb +1 -1
- data/lib/sidekiq/job_retry.rb +2 -2
- data/lib/sidekiq/launcher.rb +34 -7
- data/lib/sidekiq/logger.rb +9 -9
- data/lib/sidekiq/manager.rb +3 -3
- data/lib/sidekiq/monitor.rb +2 -2
- data/lib/sidekiq/processor.rb +5 -5
- data/lib/sidekiq/rails.rb +16 -18
- data/lib/sidekiq/redis_connection.rb +21 -13
- data/lib/sidekiq/sd_notify.rb +149 -0
- data/lib/sidekiq/systemd.rb +24 -0
- data/lib/sidekiq/testing.rb +1 -1
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +16 -8
- data/lib/sidekiq/web/application.rb +15 -9
- data/lib/sidekiq/web/csrf_protection.rb +153 -0
- data/lib/sidekiq/web/helpers.rb +4 -7
- data/lib/sidekiq/web/router.rb +2 -4
- data/lib/sidekiq/worker.rb +4 -7
- data/sidekiq.gemspec +2 -3
- data/web/assets/javascripts/application.js +24 -21
- data/web/assets/stylesheets/application-dark.css +132 -124
- data/web/assets/stylesheets/application.css +5 -0
- data/web/locales/en.yml +2 -0
- data/web/locales/fr.yml +2 -2
- data/web/locales/ja.yml +2 -0
- data/web/locales/lt.yml +83 -0
- data/web/locales/pl.yml +4 -4
- data/web/locales/vi.yml +83 -0
- data/web/views/layout.erb +1 -1
- data/web/views/queues.erb +8 -0
- metadata +14 -23
data/Pro-Changes.md
CHANGED
@@ -2,7 +2,21 @@
|
|
2
2
|
|
3
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
4
|
|
5
|
-
Please see [
|
5
|
+
Please see [sidekiq.org](https://sidekiq.org/) for more details and how to buy.
|
6
|
+
|
7
|
+
5.1.0
|
8
|
+
---------
|
9
|
+
|
10
|
+
- Remove old Statsd metrics with `WorkerName` in the name [#4377]
|
11
|
+
```
|
12
|
+
job.WorkerName.count -> job.count with tag worker:WorkerName
|
13
|
+
job.WorkerName.perform -> job.perform with tag worker:WorkerName
|
14
|
+
job.WorkerName.failure -> job.failure with tag worker:WorkerName
|
15
|
+
```
|
16
|
+
- Remove `concurrent-ruby` gem dependency [#4586]
|
17
|
+
- Update `constantize` for batch callbacks. [#4469]
|
18
|
+
- Add queue tag to `jobs.recovered.fetch` metric [#4594]
|
19
|
+
- Refactor Pro's fetch infrastructure [#4602]
|
6
20
|
|
7
21
|
5.0.1
|
8
22
|
---------
|
data/README.md
CHANGED
@@ -2,11 +2,8 @@ Sidekiq
|
|
2
2
|
==============
|
3
3
|
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/sidekiq.svg)](https://rubygems.org/gems/sidekiq)
|
5
|
-
[![
|
6
|
-
[![Test Coverage](https://codeclimate.com/github/mperham/sidekiq/badges/coverage.svg)](https://codeclimate.com/github/mperham/sidekiq/coverage)
|
5
|
+
[![Codecov](https://codecov.io/gh/mperham/sidekiq/branch/master/graph/badge.svg)](https://codecov.io/gh/mperham/sidekiq)
|
7
6
|
[![Build Status](https://circleci.com/gh/mperham/sidekiq/tree/master.svg?style=svg)](https://circleci.com/gh/mperham/sidekiq/tree/master)
|
8
|
-
[![Gitter Chat](https://badges.gitter.im/mperham/sidekiq.svg)](https://gitter.im/mperham/sidekiq)
|
9
|
-
|
10
7
|
|
11
8
|
Simple, efficient background processing for Ruby.
|
12
9
|
|
@@ -94,4 +91,4 @@ Please see [LICENSE](https://github.com/mperham/sidekiq/blob/master/LICENSE) for
|
|
94
91
|
Author
|
95
92
|
-----------------
|
96
93
|
|
97
|
-
Mike Perham, [@
|
94
|
+
Mike Perham, [@getajobmike](https://twitter.com/getajobmike) / [@sidekiq](https://twitter.com/sidekiq), [https://www.mikeperham.com](https://www.mikeperham.com) / [https://www.contribsys.com](https://www.contribsys.com)
|
data/bin/sidekiq
CHANGED
@@ -6,13 +6,37 @@ $TESTING = false
|
|
6
6
|
|
7
7
|
require_relative '../lib/sidekiq/cli'
|
8
8
|
|
9
|
+
def integrate_with_systemd
|
10
|
+
return unless ENV["NOTIFY_SOCKET"]
|
11
|
+
|
12
|
+
Sidekiq.configure_server do |config|
|
13
|
+
Sidekiq.logger.info "Enabling systemd notification integration"
|
14
|
+
require "sidekiq/sd_notify"
|
15
|
+
config.on(:startup) do
|
16
|
+
Sidekiq::SdNotify.ready
|
17
|
+
end
|
18
|
+
config.on(:shutdown) do
|
19
|
+
Sidekiq::SdNotify.stopping
|
20
|
+
end
|
21
|
+
Sidekiq.start_watchdog if Sidekiq::SdNotify.watchdog?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
9
25
|
begin
|
10
26
|
cli = Sidekiq::CLI.instance
|
11
27
|
cli.parse
|
28
|
+
|
29
|
+
integrate_with_systemd
|
30
|
+
|
12
31
|
cli.run
|
13
32
|
rescue => e
|
14
33
|
raise e if $DEBUG
|
15
|
-
|
16
|
-
|
34
|
+
if Sidekiq.error_handlers.length == 0
|
35
|
+
STDERR.puts e.message
|
36
|
+
STDERR.puts e.backtrace.join("\n")
|
37
|
+
else
|
38
|
+
cli.handle_exception e
|
39
|
+
end
|
40
|
+
|
17
41
|
exit 1
|
18
42
|
end
|
data/lib/sidekiq.rb
CHANGED
@@ -20,6 +20,7 @@ module Sidekiq
|
|
20
20
|
labels: [],
|
21
21
|
concurrency: 10,
|
22
22
|
require: ".",
|
23
|
+
strict: true,
|
23
24
|
environment: nil,
|
24
25
|
timeout: 25,
|
25
26
|
poll_interval_average: nil,
|
@@ -30,16 +31,16 @@ module Sidekiq
|
|
30
31
|
startup: [],
|
31
32
|
quiet: [],
|
32
33
|
shutdown: [],
|
33
|
-
heartbeat: []
|
34
|
+
heartbeat: []
|
34
35
|
},
|
35
36
|
dead_max_jobs: 10_000,
|
36
37
|
dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
|
37
|
-
reloader: proc { |&block| block.call }
|
38
|
+
reloader: proc { |&block| block.call }
|
38
39
|
}
|
39
40
|
|
40
41
|
DEFAULT_WORKER_OPTIONS = {
|
41
42
|
"retry" => true,
|
42
|
-
"queue" => "default"
|
43
|
+
"queue" => "default"
|
43
44
|
}
|
44
45
|
|
45
46
|
FAKE_INFO = {
|
@@ -47,7 +48,7 @@ module Sidekiq
|
|
47
48
|
"uptime_in_days" => "9999",
|
48
49
|
"connected_clients" => "9999",
|
49
50
|
"used_memory_human" => "9P",
|
50
|
-
"used_memory_peak_human" => "9P"
|
51
|
+
"used_memory_peak_human" => "9P"
|
51
52
|
}
|
52
53
|
|
53
54
|
def self.❨╯°□°❩╯︵┻━┻
|
@@ -95,10 +96,11 @@ module Sidekiq
|
|
95
96
|
retryable = true
|
96
97
|
begin
|
97
98
|
yield conn
|
98
|
-
rescue Redis::
|
99
|
+
rescue Redis::BaseError => ex
|
99
100
|
# 2550 Failover can cause the server to become a replica, need
|
100
101
|
# to disconnect and reopen the socket to get back to the primary.
|
101
|
-
if
|
102
|
+
# 4495 Use the same logic if we have a "Not enough replicas" error from the primary
|
103
|
+
if retryable && ex.message =~ /READONLY|NOREPLICAS/
|
102
104
|
conn.disconnect!
|
103
105
|
retryable = false
|
104
106
|
retry
|
@@ -154,7 +156,7 @@ module Sidekiq
|
|
154
156
|
|
155
157
|
def self.default_worker_options=(hash)
|
156
158
|
# stringify
|
157
|
-
@default_worker_options = default_worker_options.merge(
|
159
|
+
@default_worker_options = default_worker_options.merge(hash.transform_keys(&:to_s))
|
158
160
|
end
|
159
161
|
|
160
162
|
def self.default_worker_options
|
@@ -210,6 +212,10 @@ module Sidekiq
|
|
210
212
|
@logger = logger
|
211
213
|
end
|
212
214
|
|
215
|
+
def self.pro?
|
216
|
+
defined?(Sidekiq::Pro)
|
217
|
+
end
|
218
|
+
|
213
219
|
# How frequently Redis should be checked by a random Sidekiq process for
|
214
220
|
# scheduled and retriable jobs. Each individual process will take turns by
|
215
221
|
# waiting some multiple of this value.
|
data/lib/sidekiq/api.rb
CHANGED
@@ -105,7 +105,7 @@ module Sidekiq
|
|
105
105
|
|
106
106
|
default_queue_latency: default_queue_latency,
|
107
107
|
workers_size: workers_size,
|
108
|
-
enqueued: enqueued
|
108
|
+
enqueued: enqueued
|
109
109
|
}
|
110
110
|
end
|
111
111
|
|
@@ -273,7 +273,7 @@ module Sidekiq
|
|
273
273
|
def clear
|
274
274
|
Sidekiq.redis do |conn|
|
275
275
|
conn.multi do
|
276
|
-
conn.
|
276
|
+
conn.unlink(@rname)
|
277
277
|
conn.srem("queues", name)
|
278
278
|
end
|
279
279
|
end
|
@@ -562,7 +562,7 @@ module Sidekiq
|
|
562
562
|
|
563
563
|
def clear
|
564
564
|
Sidekiq.redis do |conn|
|
565
|
-
conn.
|
565
|
+
conn.unlink(name)
|
566
566
|
end
|
567
567
|
end
|
568
568
|
alias_method :💣, :clear
|
@@ -921,12 +921,16 @@ module Sidekiq
|
|
921
921
|
procs = conn.sscan_each("processes").to_a
|
922
922
|
procs.sort.each do |key|
|
923
923
|
valid, workers = conn.pipelined {
|
924
|
-
conn.exists(key)
|
924
|
+
conn.exists?(key)
|
925
925
|
conn.hgetall("#{key}:workers")
|
926
926
|
}
|
927
927
|
next unless valid
|
928
928
|
workers.each_pair do |tid, json|
|
929
|
-
|
929
|
+
hsh = Sidekiq.load_json(json)
|
930
|
+
p = hsh["payload"]
|
931
|
+
# avoid breaking API, this is a side effect of the JSON optimization in #4316
|
932
|
+
hsh["payload"] = Sidekiq.load_json(p) if p.is_a?(String)
|
933
|
+
yield key, tid, hsh
|
930
934
|
end
|
931
935
|
end
|
932
936
|
end
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -38,6 +38,7 @@ module Sidekiq
|
|
38
38
|
if environment == "development" && $stdout.tty? && Sidekiq.log_formatter.is_a?(Sidekiq::Logger::Formatters::Pretty)
|
39
39
|
print_banner
|
40
40
|
end
|
41
|
+
logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
|
41
42
|
|
42
43
|
self_read, self_write = IO.pipe
|
43
44
|
sigs = %w[INT TERM TTIN TSTP]
|
@@ -53,7 +54,7 @@ module Sidekiq
|
|
53
54
|
|
54
55
|
logger.info "Running in #{RUBY_DESCRIPTION}"
|
55
56
|
logger.info Sidekiq::LICENSE
|
56
|
-
logger.info "Upgrade to Sidekiq Pro for more features and support:
|
57
|
+
logger.info "Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org" unless defined?(::Sidekiq::Pro)
|
57
58
|
|
58
59
|
# touch the connection pool so it is created before we
|
59
60
|
# fire startup and start multithreading.
|
@@ -162,7 +163,7 @@ module Sidekiq
|
|
162
163
|
Sidekiq.logger.warn "<no backtrace available>"
|
163
164
|
end
|
164
165
|
end
|
165
|
-
}
|
166
|
+
}
|
166
167
|
}
|
167
168
|
UNHANDLED_SIGNAL_HANDLER = ->(cli) { Sidekiq.logger.info "No signal handler registered, ignoring" }
|
168
169
|
SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
|
@@ -181,7 +182,11 @@ module Sidekiq
|
|
181
182
|
end
|
182
183
|
|
183
184
|
def set_environment(cli_env)
|
184
|
-
|
185
|
+
# See #984 for discussion.
|
186
|
+
# APP_ENV is now the preferred ENV term since it is not tech-specific.
|
187
|
+
# Both Sinatra 2.0+ and Sidekiq support this term.
|
188
|
+
# RAILS_ENV and RACK_ENV are there for legacy support.
|
189
|
+
@environment = cli_env || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
185
190
|
end
|
186
191
|
|
187
192
|
def symbolize_keys_deep!(hash)
|
@@ -223,8 +228,7 @@ module Sidekiq
|
|
223
228
|
opts = parse_config(opts[:config_file]).merge(opts) if opts[:config_file]
|
224
229
|
|
225
230
|
# set defaults
|
226
|
-
opts[:queues] = ["default"] if opts[:queues].nil?
|
227
|
-
opts[:strict] = true if opts[:strict].nil?
|
231
|
+
opts[:queues] = ["default"] if opts[:queues].nil?
|
228
232
|
opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if opts[:concurrency].nil? && ENV["RAILS_MAX_THREADS"]
|
229
233
|
|
230
234
|
# merge with defaults
|
@@ -353,6 +357,12 @@ module Sidekiq
|
|
353
357
|
Sidekiq.logger.level = ::Logger::DEBUG if options[:verbose]
|
354
358
|
end
|
355
359
|
|
360
|
+
INTERNAL_OPTIONS = [
|
361
|
+
# These are options that are set internally and cannot be
|
362
|
+
# set via the config file or command line arguments.
|
363
|
+
:strict
|
364
|
+
]
|
365
|
+
|
356
366
|
def parse_config(path)
|
357
367
|
opts = YAML.load(ERB.new(File.read(path)).result) || {}
|
358
368
|
|
@@ -363,6 +373,8 @@ module Sidekiq
|
|
363
373
|
end
|
364
374
|
|
365
375
|
opts = opts.merge(opts.delete(environment.to_sym) || {})
|
376
|
+
opts.delete(*INTERNAL_OPTIONS)
|
377
|
+
|
366
378
|
parse_queues(opts, opts.delete(:queues) || [])
|
367
379
|
|
368
380
|
opts
|
@@ -374,9 +386,16 @@ module Sidekiq
|
|
374
386
|
|
375
387
|
def parse_queue(opts, queue, weight = nil)
|
376
388
|
opts[:queues] ||= []
|
389
|
+
opts[:strict] = true if opts[:strict].nil?
|
377
390
|
raise ArgumentError, "queues: #{queue} cannot be defined twice" if opts[:queues].include?(queue)
|
378
391
|
[weight.to_i, 1].max.times { opts[:queues] << queue }
|
379
392
|
opts[:strict] = false if weight.to_i > 0
|
380
393
|
end
|
394
|
+
|
395
|
+
def rails_app?
|
396
|
+
defined?(::Rails) && ::Rails.respond_to?(:application)
|
397
|
+
end
|
381
398
|
end
|
382
399
|
end
|
400
|
+
|
401
|
+
require "sidekiq/systemd"
|
data/lib/sidekiq/client.rb
CHANGED
@@ -90,16 +90,17 @@ module Sidekiq
|
|
90
90
|
# Returns an array of the of pushed jobs' jids. The number of jobs pushed can be less
|
91
91
|
# than the number given if the middleware stopped processing for one or more jobs.
|
92
92
|
def push_bulk(items)
|
93
|
-
|
94
|
-
|
95
|
-
|
93
|
+
args = items["args"]
|
94
|
+
raise ArgumentError, "Bulk arguments must be an Array of Arrays: [[1], [2]]" unless args.is_a?(Array) && args.all?(Array)
|
95
|
+
return [] if args.empty? # no jobs to push
|
96
96
|
|
97
97
|
at = items.delete("at")
|
98
98
|
raise ArgumentError, "Job 'at' must be a Numeric or an Array of Numeric timestamps" if at && (Array(at).empty? || !Array(at).all?(Numeric))
|
99
|
+
raise ArgumentError, "Job 'at' Array must have same size as 'args' Array" if at.is_a?(Array) && at.size != args.size
|
99
100
|
|
100
101
|
normed = normalize_item(items)
|
101
|
-
payloads =
|
102
|
-
copy = normed.merge("args" =>
|
102
|
+
payloads = args.map.with_index { |job_args, index|
|
103
|
+
copy = normed.merge("args" => job_args, "jid" => SecureRandom.hex(12), "enqueued_at" => Time.now.to_f)
|
103
104
|
copy["at"] = (at.is_a?(Array) ? at[index] : at) if at
|
104
105
|
|
105
106
|
result = process_single(items["class"], copy)
|
@@ -218,25 +219,35 @@ module Sidekiq
|
|
218
219
|
end
|
219
220
|
end
|
220
221
|
|
222
|
+
def validate(item)
|
223
|
+
raise(ArgumentError, "Job must be a Hash with 'class' and 'args' keys: `#{item}`") unless item.is_a?(Hash) && item.key?("class") && item.key?("args")
|
224
|
+
raise(ArgumentError, "Job args must be an Array: `#{item}`") unless item["args"].is_a?(Array)
|
225
|
+
raise(ArgumentError, "Job class must be either a Class or String representation of the class name: `#{item}`") unless item["class"].is_a?(Class) || item["class"].is_a?(String)
|
226
|
+
raise(ArgumentError, "Job 'at' must be a Numeric timestamp: `#{item}`") if item.key?("at") && !item["at"].is_a?(Numeric)
|
227
|
+
raise(ArgumentError, "Job tags must be an Array: `#{item}`") if item["tags"] && !item["tags"].is_a?(Array)
|
228
|
+
end
|
229
|
+
|
221
230
|
def normalize_item(item)
|
222
231
|
# 6.0.0 push_bulk bug, #4321
|
223
232
|
# TODO Remove after a while...
|
224
233
|
item.delete("at") if item.key?("at") && item["at"].nil?
|
225
234
|
|
226
|
-
|
227
|
-
raise(ArgumentError, "Job args must be an Array") unless item["args"].is_a?(Array)
|
228
|
-
raise(ArgumentError, "Job class must be either a Class or String representation of the class name") unless item["class"].is_a?(Class) || item["class"].is_a?(String)
|
229
|
-
raise(ArgumentError, "Job 'at' must be a Numeric timestamp") if item.key?("at") && !item["at"].is_a?(Numeric)
|
230
|
-
raise(ArgumentError, "Job tags must be an Array") if item["tags"] && !item["tags"].is_a?(Array)
|
235
|
+
validate(item)
|
231
236
|
# 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']
|
232
237
|
|
233
|
-
|
234
|
-
|
238
|
+
# merge in the default sidekiq_options for the item's class and/or wrapped element
|
239
|
+
# this allows ActiveJobs to control sidekiq_options too.
|
240
|
+
defaults = normalized_hash(item["class"])
|
241
|
+
defaults = defaults.merge(item["wrapped"].get_sidekiq_options) if item["wrapped"].respond_to?("get_sidekiq_options")
|
242
|
+
item = defaults.merge(item)
|
243
|
+
|
244
|
+
raise(ArgumentError, "Job must include a valid queue name") if item["queue"].nil? || item["queue"] == ""
|
235
245
|
|
236
246
|
item["class"] = item["class"].to_s
|
237
247
|
item["queue"] = item["queue"].to_s
|
238
248
|
item["jid"] ||= SecureRandom.hex(12)
|
239
249
|
item["created_at"] ||= Time.now.to_f
|
250
|
+
|
240
251
|
item
|
241
252
|
end
|
242
253
|
|
@@ -6,9 +6,10 @@ module Sidekiq
|
|
6
6
|
module Extensions
|
7
7
|
##
|
8
8
|
# Adds 'delay', 'delay_for' and `delay_until` methods to ActiveRecord to offload instance method
|
9
|
-
# execution to Sidekiq.
|
9
|
+
# execution to Sidekiq.
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# @example
|
12
|
+
# User.recent_signups.each { |user| user.delay.mark_as_awesome }
|
12
13
|
#
|
13
14
|
# Please note, this is not recommended as this will serialize the entire
|
14
15
|
# object to Redis. Your Sidekiq jobs should pass IDs, not entire instances.
|
@@ -5,11 +5,12 @@ require "sidekiq/extensions/generic_proxy"
|
|
5
5
|
module Sidekiq
|
6
6
|
module Extensions
|
7
7
|
##
|
8
|
-
# Adds
|
9
|
-
# execution to Sidekiq.
|
8
|
+
# Adds `delay`, `delay_for` and `delay_until` methods to all Classes to offload class method
|
9
|
+
# execution to Sidekiq.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
11
|
+
# @example
|
12
|
+
# User.delay.delete_inactive
|
13
|
+
# Wikipedia.delay.download_changes_for(Date.today)
|
13
14
|
#
|
14
15
|
class DelayedClass
|
15
16
|
include Sidekiq::Worker
|
data/lib/sidekiq/fetch.rb
CHANGED
@@ -25,8 +25,10 @@ module Sidekiq
|
|
25
25
|
}
|
26
26
|
|
27
27
|
def initialize(options)
|
28
|
-
|
29
|
-
@
|
28
|
+
raise ArgumentError, "missing queue list" unless options[:queues]
|
29
|
+
@options = options
|
30
|
+
@strictly_ordered_queues = !!@options[:strict]
|
31
|
+
@queues = @options[:queues].map { |q| "queue:#{q}" }
|
30
32
|
if @strictly_ordered_queues
|
31
33
|
@queues.uniq!
|
32
34
|
@queues << TIMEOUT
|
@@ -38,24 +40,9 @@ module Sidekiq
|
|
38
40
|
UnitOfWork.new(*work) if work
|
39
41
|
end
|
40
42
|
|
41
|
-
# Creating the Redis#brpop command takes into account any
|
42
|
-
# configured queue weights. By default Redis#brpop returns
|
43
|
-
# data from the first queue that has pending elements. We
|
44
|
-
# recreate the queue command each time we invoke Redis#brpop
|
45
|
-
# to honor weights and avoid queue starvation.
|
46
|
-
def queues_cmd
|
47
|
-
if @strictly_ordered_queues
|
48
|
-
@queues
|
49
|
-
else
|
50
|
-
queues = @queues.shuffle!.uniq
|
51
|
-
queues << TIMEOUT
|
52
|
-
queues
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
43
|
# By leaving this as a class method, it can be pluggable and used by the Manager actor. Making it
|
57
44
|
# an instance method will make it async to the Fetcher actor
|
58
|
-
def
|
45
|
+
def bulk_requeue(inprogress, options)
|
59
46
|
return if inprogress.empty?
|
60
47
|
|
61
48
|
Sidekiq.logger.debug { "Re-queueing terminated jobs" }
|
@@ -76,5 +63,20 @@ module Sidekiq
|
|
76
63
|
rescue => ex
|
77
64
|
Sidekiq.logger.warn("Failed to requeue #{inprogress.size} jobs: #{ex.message}")
|
78
65
|
end
|
66
|
+
|
67
|
+
# Creating the Redis#brpop command takes into account any
|
68
|
+
# configured queue weights. By default Redis#brpop returns
|
69
|
+
# data from the first queue that has pending elements. We
|
70
|
+
# recreate the queue command each time we invoke Redis#brpop
|
71
|
+
# to honor weights and avoid queue starvation.
|
72
|
+
def queues_cmd
|
73
|
+
if @strictly_ordered_queues
|
74
|
+
@queues
|
75
|
+
else
|
76
|
+
queues = @queues.shuffle!.uniq
|
77
|
+
queues << TIMEOUT
|
78
|
+
queues
|
79
|
+
end
|
80
|
+
end
|
79
81
|
end
|
80
82
|
end
|