sidekiq 6.4.2 → 6.5.5
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/Changes.md +52 -0
- data/bin/sidekiqload +15 -3
- data/lib/sidekiq/api.rb +163 -32
- data/lib/sidekiq/cli.rb +34 -32
- data/lib/sidekiq/client.rb +4 -4
- data/lib/sidekiq/component.rb +65 -0
- data/lib/sidekiq/delay.rb +1 -1
- data/lib/sidekiq/fetch.rb +16 -14
- data/lib/sidekiq/job_retry.rb +60 -39
- data/lib/sidekiq/job_util.rb +7 -3
- data/lib/sidekiq/launcher.rb +22 -19
- data/lib/sidekiq/logger.rb +1 -1
- data/lib/sidekiq/manager.rb +23 -20
- data/lib/sidekiq/metrics/deploy.rb +47 -0
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +94 -0
- data/lib/sidekiq/metrics/tracking.rb +134 -0
- data/lib/sidekiq/middleware/chain.rb +82 -38
- data/lib/sidekiq/middleware/current_attributes.rb +10 -4
- data/lib/sidekiq/middleware/i18n.rb +2 -0
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/paginator.rb +2 -2
- data/lib/sidekiq/processor.rb +21 -15
- data/lib/sidekiq/rails.rb +5 -5
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +80 -47
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +12 -17
- data/lib/sidekiq/testing.rb +1 -1
- data/lib/sidekiq/transaction_aware_client.rb +45 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +3 -3
- data/lib/sidekiq/web/application.rb +18 -5
- data/lib/sidekiq/web/helpers.rb +25 -2
- data/lib/sidekiq/web.rb +5 -1
- data/lib/sidekiq/worker.rb +2 -1
- data/lib/sidekiq.rb +87 -18
- data/sidekiq.gemspec +1 -1
- data/web/assets/javascripts/application.js +1 -1
- data/web/assets/javascripts/chart.min.js +13 -0
- data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
- data/web/assets/javascripts/dashboard.js +0 -17
- data/web/assets/javascripts/graph.js +16 -0
- data/web/assets/javascripts/metrics.js +262 -0
- data/web/assets/stylesheets/application.css +44 -1
- data/web/locales/el.yml +43 -19
- data/web/locales/en.yml +7 -0
- data/web/locales/pt-br.yml +27 -9
- data/web/views/_nav.erb +1 -1
- data/web/views/busy.erb +1 -1
- data/web/views/dashboard.erb +1 -0
- data/web/views/metrics.erb +69 -0
- data/web/views/metrics_for_job.erb +87 -0
- data/web/views/queue.erb +5 -1
- metadata +19 -6
- data/lib/sidekiq/exception_handler.rb +0 -27
- data/lib/sidekiq/util.rb +0 -108
@@ -5,8 +5,81 @@ require "redis"
|
|
5
5
|
require "uri"
|
6
6
|
|
7
7
|
module Sidekiq
|
8
|
-
|
8
|
+
module RedisConnection
|
9
|
+
class RedisAdapter
|
10
|
+
BaseError = Redis::BaseError
|
11
|
+
CommandError = Redis::CommandError
|
12
|
+
|
13
|
+
def initialize(options)
|
14
|
+
warn("Usage of the 'redis' gem within Sidekiq itself is deprecated, Sidekiq 7.0 will only use the new, simpler 'redis-client' gem", caller) if ENV["SIDEKIQ_REDIS_CLIENT"] == "1"
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
def new_client
|
19
|
+
namespace = @options[:namespace]
|
20
|
+
|
21
|
+
client = Redis.new client_opts(@options)
|
22
|
+
if namespace
|
23
|
+
begin
|
24
|
+
require "redis/namespace"
|
25
|
+
Redis::Namespace.new(namespace, redis: client)
|
26
|
+
rescue LoadError
|
27
|
+
Sidekiq.logger.error("Your Redis configuration uses the namespace '#{namespace}' but the redis-namespace gem is not included in the Gemfile." \
|
28
|
+
"Add the gem to your Gemfile to continue using a namespace. Otherwise, remove the namespace parameter.")
|
29
|
+
exit(-127)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
client
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def client_opts(options)
|
39
|
+
opts = options.dup
|
40
|
+
if opts[:namespace]
|
41
|
+
opts.delete(:namespace)
|
42
|
+
end
|
43
|
+
|
44
|
+
if opts[:network_timeout]
|
45
|
+
opts[:timeout] = opts[:network_timeout]
|
46
|
+
opts.delete(:network_timeout)
|
47
|
+
end
|
48
|
+
|
49
|
+
opts[:driver] ||= Redis::Connection.drivers.last || "ruby"
|
50
|
+
|
51
|
+
# Issue #3303, redis-rb will silently retry an operation.
|
52
|
+
# This can lead to duplicate jobs if Sidekiq::Client's LPUSH
|
53
|
+
# is performed twice but I believe this is much, much rarer
|
54
|
+
# than the reconnect silently fixing a problem; we keep it
|
55
|
+
# on by default.
|
56
|
+
opts[:reconnect_attempts] ||= 1
|
57
|
+
|
58
|
+
opts
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
@adapter = RedisAdapter
|
63
|
+
|
9
64
|
class << self
|
65
|
+
attr_reader :adapter
|
66
|
+
|
67
|
+
# RedisConnection.adapter = :redis
|
68
|
+
# RedisConnection.adapter = :redis_client
|
69
|
+
def adapter=(adapter)
|
70
|
+
raise "no" if adapter == self
|
71
|
+
result = case adapter
|
72
|
+
when :redis
|
73
|
+
RedisAdapter
|
74
|
+
when Class
|
75
|
+
adapter
|
76
|
+
else
|
77
|
+
require "sidekiq/#{adapter}_adapter"
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
@adapter = result if result
|
81
|
+
end
|
82
|
+
|
10
83
|
def create(options = {})
|
11
84
|
symbolized_options = options.transform_keys(&:to_sym)
|
12
85
|
|
@@ -19,20 +92,21 @@ module Sidekiq
|
|
19
92
|
elsif Sidekiq.server?
|
20
93
|
# Give ourselves plenty of connections. pool is lazy
|
21
94
|
# so we won't create them until we need them.
|
22
|
-
Sidekiq
|
95
|
+
Sidekiq[:concurrency] + 5
|
23
96
|
elsif ENV["RAILS_MAX_THREADS"]
|
24
97
|
Integer(ENV["RAILS_MAX_THREADS"])
|
25
98
|
else
|
26
99
|
5
|
27
100
|
end
|
28
101
|
|
29
|
-
verify_sizing(size, Sidekiq
|
102
|
+
verify_sizing(size, Sidekiq[:concurrency]) if Sidekiq.server?
|
30
103
|
|
31
104
|
pool_timeout = symbolized_options[:pool_timeout] || 1
|
32
105
|
log_info(symbolized_options)
|
33
106
|
|
107
|
+
redis_config = adapter.new(symbolized_options)
|
34
108
|
ConnectionPool.new(timeout: pool_timeout, size: size) do
|
35
|
-
|
109
|
+
redis_config.new_client
|
36
110
|
end
|
37
111
|
end
|
38
112
|
|
@@ -50,47 +124,6 @@ module Sidekiq
|
|
50
124
|
raise ArgumentError, "Your Redis connection pool is too small for Sidekiq. Your pool has #{size} connections but must have at least #{concurrency + 2}" if size < (concurrency + 2)
|
51
125
|
end
|
52
126
|
|
53
|
-
def build_client(options)
|
54
|
-
namespace = options[:namespace]
|
55
|
-
|
56
|
-
client = Redis.new client_opts(options)
|
57
|
-
if namespace
|
58
|
-
begin
|
59
|
-
require "redis/namespace"
|
60
|
-
Redis::Namespace.new(namespace, redis: client)
|
61
|
-
rescue LoadError
|
62
|
-
Sidekiq.logger.error("Your Redis configuration uses the namespace '#{namespace}' but the redis-namespace gem is not included in the Gemfile." \
|
63
|
-
"Add the gem to your Gemfile to continue using a namespace. Otherwise, remove the namespace parameter.")
|
64
|
-
exit(-127)
|
65
|
-
end
|
66
|
-
else
|
67
|
-
client
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def client_opts(options)
|
72
|
-
opts = options.dup
|
73
|
-
if opts[:namespace]
|
74
|
-
opts.delete(:namespace)
|
75
|
-
end
|
76
|
-
|
77
|
-
if opts[:network_timeout]
|
78
|
-
opts[:timeout] = opts[:network_timeout]
|
79
|
-
opts.delete(:network_timeout)
|
80
|
-
end
|
81
|
-
|
82
|
-
opts[:driver] ||= Redis::Connection.drivers.last || "ruby"
|
83
|
-
|
84
|
-
# Issue #3303, redis-rb will silently retry an operation.
|
85
|
-
# This can lead to duplicate jobs if Sidekiq::Client's LPUSH
|
86
|
-
# is performed twice but I believe this is much, much rarer
|
87
|
-
# than the reconnect silently fixing a problem; we keep it
|
88
|
-
# on by default.
|
89
|
-
opts[:reconnect_attempts] ||= 1
|
90
|
-
|
91
|
-
opts
|
92
|
-
end
|
93
|
-
|
94
127
|
def log_info(options)
|
95
128
|
redacted = "REDACTED"
|
96
129
|
|
@@ -110,9 +143,9 @@ module Sidekiq
|
|
110
143
|
sentinel[:password] = redacted if sentinel[:password]
|
111
144
|
end
|
112
145
|
if Sidekiq.server?
|
113
|
-
Sidekiq.logger.info("Booting Sidekiq #{Sidekiq::VERSION} with
|
146
|
+
Sidekiq.logger.info("Booting Sidekiq #{Sidekiq::VERSION} with #{adapter.name} options #{scrubbed_options}")
|
114
147
|
else
|
115
|
-
Sidekiq.logger.debug("#{Sidekiq::NAME} client with
|
148
|
+
Sidekiq.logger.debug("#{Sidekiq::NAME} client with #{adapter.name} options #{scrubbed_options}")
|
116
149
|
end
|
117
150
|
end
|
118
151
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
class RingBuffer
|
5
|
+
include Enumerable
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@buf, :[], :each, :size
|
8
|
+
|
9
|
+
def initialize(size, default = 0)
|
10
|
+
@size = size
|
11
|
+
@buf = Array.new(size, default)
|
12
|
+
@index = 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def <<(element)
|
16
|
+
@buf[@index % @size] = element
|
17
|
+
@index += 1
|
18
|
+
element
|
19
|
+
end
|
20
|
+
|
21
|
+
def buffer
|
22
|
+
@buf
|
23
|
+
end
|
24
|
+
|
25
|
+
def reset(default = 0)
|
26
|
+
@buf.fill(default)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/sidekiq/scheduled.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "sidekiq"
|
4
|
-
require "sidekiq/
|
5
|
-
require "sidekiq/api"
|
4
|
+
require "sidekiq/component"
|
6
5
|
|
7
6
|
module Sidekiq
|
8
7
|
module Scheduled
|
@@ -52,8 +51,8 @@ module Sidekiq
|
|
52
51
|
@lua_zpopbyscore_sha = raw_conn.script(:load, LUA_ZPOPBYSCORE)
|
53
52
|
end
|
54
53
|
|
55
|
-
conn.evalsha(@lua_zpopbyscore_sha, keys
|
56
|
-
rescue
|
54
|
+
conn.evalsha(@lua_zpopbyscore_sha, keys, argv)
|
55
|
+
rescue RedisConnection.adapter::CommandError => e
|
57
56
|
raise unless e.message.start_with?("NOSCRIPT")
|
58
57
|
|
59
58
|
@lua_zpopbyscore_sha = nil
|
@@ -67,12 +66,13 @@ module Sidekiq
|
|
67
66
|
# just pops the job back onto its original queue so the
|
68
67
|
# workers can pick it up like any other job.
|
69
68
|
class Poller
|
70
|
-
include
|
69
|
+
include Sidekiq::Component
|
71
70
|
|
72
71
|
INITIAL_WAIT = 10
|
73
72
|
|
74
|
-
def initialize
|
75
|
-
@
|
73
|
+
def initialize(options)
|
74
|
+
@config = options
|
75
|
+
@enq = (options[:scheduled_enq] || Sidekiq::Scheduled::Enq).new
|
76
76
|
@sleeper = ConnectionPool::TimedStack.new
|
77
77
|
@done = false
|
78
78
|
@thread = nil
|
@@ -100,7 +100,7 @@ module Sidekiq
|
|
100
100
|
enqueue
|
101
101
|
wait
|
102
102
|
end
|
103
|
-
|
103
|
+
logger.info("Scheduler exiting...")
|
104
104
|
}
|
105
105
|
end
|
106
106
|
|
@@ -171,24 +171,19 @@ module Sidekiq
|
|
171
171
|
#
|
172
172
|
# We only do this if poll_interval_average is unset (the default).
|
173
173
|
def poll_interval_average
|
174
|
-
|
174
|
+
@config[:poll_interval_average] ||= scaled_poll_interval
|
175
175
|
end
|
176
176
|
|
177
177
|
# Calculates an average poll interval based on the number of known Sidekiq processes.
|
178
178
|
# This minimizes a single point of failure by dispersing check-ins but without taxing
|
179
179
|
# Redis if you run many Sidekiq processes.
|
180
180
|
def scaled_poll_interval
|
181
|
-
process_count *
|
181
|
+
process_count * @config[:average_scheduled_poll_interval]
|
182
182
|
end
|
183
183
|
|
184
184
|
def process_count
|
185
|
-
|
186
|
-
# expensive at scale. Cut it down by 90% with this counter.
|
187
|
-
# NB: This method is only called by the scheduler thread so we
|
188
|
-
# don't need to worry about the thread safety of +=.
|
189
|
-
pcount = Sidekiq::ProcessSet.new(@count_calls % 10 == 0).size
|
185
|
+
pcount = Sidekiq.redis { |conn| conn.scard("processes") }
|
190
186
|
pcount = 1 if pcount == 0
|
191
|
-
@count_calls += 1
|
192
187
|
pcount
|
193
188
|
end
|
194
189
|
|
@@ -197,7 +192,7 @@ module Sidekiq
|
|
197
192
|
# to give time for the heartbeat to register (if the poll interval is going to be calculated by the number
|
198
193
|
# of workers), and 5 random seconds to ensure they don't all hit Redis at the same time.
|
199
194
|
total = 0
|
200
|
-
total += INITIAL_WAIT unless
|
195
|
+
total += INITIAL_WAIT unless @config[:poll_interval_average]
|
201
196
|
total += (5 * rand)
|
202
197
|
|
203
198
|
@sleeper.pop(total)
|
data/lib/sidekiq/testing.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "securerandom"
|
4
|
+
require "sidekiq/client"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
class TransactionAwareClient
|
8
|
+
def initialize(redis_pool)
|
9
|
+
@redis_client = Client.new(redis_pool)
|
10
|
+
end
|
11
|
+
|
12
|
+
def push(item)
|
13
|
+
# pre-allocate the JID so we can return it immediately and
|
14
|
+
# save it to the database as part of the transaction.
|
15
|
+
item["jid"] ||= SecureRandom.hex(12)
|
16
|
+
AfterCommitEverywhere.after_commit { @redis_client.push(item) }
|
17
|
+
item["jid"]
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# We don't provide transactionality for push_bulk because we don't want
|
22
|
+
# to hold potentially hundreds of thousands of job records in memory due to
|
23
|
+
# a long running enqueue process.
|
24
|
+
def push_bulk(items)
|
25
|
+
@redis_client.push_bulk(items)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Use `Sidekiq.transactional_push!` in your sidekiq.rb initializer
|
32
|
+
module Sidekiq
|
33
|
+
def self.transactional_push!
|
34
|
+
begin
|
35
|
+
require "after_commit_everywhere"
|
36
|
+
rescue LoadError
|
37
|
+
Sidekiq.logger.error("You need to add after_commit_everywhere to your Gemfile to use Sidekiq's transactional client")
|
38
|
+
raise
|
39
|
+
end
|
40
|
+
|
41
|
+
default_job_options["client_class"] = Sidekiq::TransactionAwareClient
|
42
|
+
Sidekiq::JobUtil::TRANSIENT_ATTRIBUTES << "client_class"
|
43
|
+
true
|
44
|
+
end
|
45
|
+
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
@@ -15,11 +15,11 @@ module Sidekiq
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def halt(res)
|
18
|
-
throw :halt, [res, {"
|
18
|
+
throw :halt, [res, {"content-type" => "text/plain"}, [res.to_s]]
|
19
19
|
end
|
20
20
|
|
21
21
|
def redirect(location)
|
22
|
-
throw :halt, [302, {"
|
22
|
+
throw :halt, [302, {"location" => "#{request.base_url}#{location}"}, []]
|
23
23
|
end
|
24
24
|
|
25
25
|
def params
|
@@ -68,7 +68,7 @@ module Sidekiq
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def json(payload)
|
71
|
-
[200, {"
|
71
|
+
[200, {"content-type" => "application/json", "cache-control" => "private, no-store"}, [Sidekiq.dump_json(payload)]]
|
72
72
|
end
|
73
73
|
|
74
74
|
def initialize(env, block)
|
@@ -60,6 +60,19 @@ module Sidekiq
|
|
60
60
|
erb(:dashboard)
|
61
61
|
end
|
62
62
|
|
63
|
+
get "/metrics" do
|
64
|
+
q = Sidekiq::Metrics::Query.new
|
65
|
+
@query_result = q.top_jobs
|
66
|
+
erb(:metrics)
|
67
|
+
end
|
68
|
+
|
69
|
+
get "/metrics/:name" do
|
70
|
+
@name = route_params[:name]
|
71
|
+
q = Sidekiq::Metrics::Query.new
|
72
|
+
@query_result = q.for_job(@name)
|
73
|
+
erb(:metrics_for_job)
|
74
|
+
end
|
75
|
+
|
63
76
|
get "/busy" do
|
64
77
|
erb(:busy)
|
65
78
|
end
|
@@ -299,7 +312,7 @@ module Sidekiq
|
|
299
312
|
|
300
313
|
def call(env)
|
301
314
|
action = self.class.match(env)
|
302
|
-
return [404, {"
|
315
|
+
return [404, {"content-type" => "text/plain", "x-cascade" => "pass"}, ["Not Found"]] unless action
|
303
316
|
|
304
317
|
app = @klass
|
305
318
|
resp = catch(:halt) do
|
@@ -316,10 +329,10 @@ module Sidekiq
|
|
316
329
|
else
|
317
330
|
# rendered content goes here
|
318
331
|
headers = {
|
319
|
-
"
|
320
|
-
"
|
321
|
-
"
|
322
|
-
"
|
332
|
+
"content-type" => "text/html",
|
333
|
+
"cache-control" => "private, no-store",
|
334
|
+
"content-language" => action.locale,
|
335
|
+
"content-security-policy" => CSP_HEADER
|
323
336
|
}
|
324
337
|
# we'll let Rack calculate Content-Length for us.
|
325
338
|
[200, headers, [resp]]
|
data/lib/sidekiq/web/helpers.rb
CHANGED
@@ -15,7 +15,7 @@ module Sidekiq
|
|
15
15
|
# so extensions can be localized
|
16
16
|
@strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
|
17
17
|
find_locale_files(lang).each do |file|
|
18
|
-
strs = YAML.
|
18
|
+
strs = YAML.safe_load(File.open(file))
|
19
19
|
global.merge!(strs[lang])
|
20
20
|
end
|
21
21
|
end
|
@@ -148,6 +148,29 @@ module Sidekiq
|
|
148
148
|
@processes ||= Sidekiq::ProcessSet.new
|
149
149
|
end
|
150
150
|
|
151
|
+
# Sorts processes by hostname following the natural sort order so that
|
152
|
+
# 'worker.1' < 'worker.2' < 'worker.10' < 'worker.20'
|
153
|
+
# '2.1.1.1' < '192.168.0.2' < '192.168.0.10'
|
154
|
+
def sorted_processes
|
155
|
+
@sorted_processes ||= begin
|
156
|
+
return processes unless processes.all? { |p| p["hostname"] }
|
157
|
+
|
158
|
+
split_characters = /[._-]/
|
159
|
+
|
160
|
+
padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
|
161
|
+
|
162
|
+
processes.to_a.sort_by do |process|
|
163
|
+
process["hostname"].split(split_characters).map do |substring|
|
164
|
+
# Left-pad the substring with '0' if it starts with a number or 'a'
|
165
|
+
# otherwise, so that '25' < 192' < 'a' ('025' < '192' < 'aaa')
|
166
|
+
padding_char = substring[0].match?(/\d/) ? "0" : "a"
|
167
|
+
|
168
|
+
substring.rjust(padding, padding_char)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
151
174
|
def stats
|
152
175
|
@stats ||= Sidekiq::Stats.new
|
153
176
|
end
|
@@ -301,7 +324,7 @@ module Sidekiq
|
|
301
324
|
end
|
302
325
|
|
303
326
|
def environment_title_prefix
|
304
|
-
environment = Sidekiq
|
327
|
+
environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
305
328
|
|
306
329
|
"[#{environment.upcase}] " unless environment == "production"
|
307
330
|
end
|
data/lib/sidekiq/web.rb
CHANGED
@@ -33,6 +33,10 @@ module Sidekiq
|
|
33
33
|
"Dead" => "morgue"
|
34
34
|
}
|
35
35
|
|
36
|
+
if ENV["SIDEKIQ_METRICS_BETA"] == "1"
|
37
|
+
DEFAULT_TABS["Metrics"] = "metrics"
|
38
|
+
end
|
39
|
+
|
36
40
|
class << self
|
37
41
|
def settings
|
38
42
|
self
|
@@ -144,7 +148,7 @@ module Sidekiq
|
|
144
148
|
m = middlewares
|
145
149
|
|
146
150
|
rules = []
|
147
|
-
rules = [[:all, {"
|
151
|
+
rules = [[:all, {"cache-control" => "public, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
|
148
152
|
|
149
153
|
::Rack::Builder.new do
|
150
154
|
use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
|
data/lib/sidekiq/worker.rb
CHANGED
@@ -359,7 +359,8 @@ module Sidekiq
|
|
359
359
|
|
360
360
|
def build_client # :nodoc:
|
361
361
|
pool = Thread.current[:sidekiq_via_pool] || get_sidekiq_options["pool"] || Sidekiq.redis_pool
|
362
|
-
Sidekiq::Client
|
362
|
+
client_class = get_sidekiq_options["client_class"] || Sidekiq::Client
|
363
|
+
client_class.new(pool)
|
363
364
|
end
|
364
365
|
end
|
365
366
|
end
|