sidekiq 3.3.0 → 3.3.1
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/.travis.yml +7 -9
- data/Changes.md +16 -0
- data/Pro-2.0-Upgrade.md +102 -0
- data/Pro-Changes.md +14 -0
- data/README.md +3 -3
- data/Rakefile +0 -1
- data/bin/sidekiqctl +16 -14
- data/lib/sidekiq.rb +14 -14
- data/lib/sidekiq/api.rb +110 -40
- data/lib/sidekiq/cli.rb +11 -11
- data/lib/sidekiq/client.rb +13 -14
- data/lib/sidekiq/extensions/action_mailer.rb +5 -1
- data/lib/sidekiq/launcher.rb +4 -1
- data/lib/sidekiq/logging.rb +8 -7
- data/lib/sidekiq/manager.rb +9 -2
- data/lib/sidekiq/middleware/server/logging.rb +1 -1
- data/lib/sidekiq/middleware/server/retry_jobs.rb +4 -4
- data/lib/sidekiq/processor.rb +6 -6
- data/lib/sidekiq/testing.rb +8 -9
- data/lib/sidekiq/util.rb +8 -3
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +33 -20
- data/lib/sidekiq/web_helpers.rb +13 -9
- data/lib/sidekiq/worker.rb +1 -2
- data/sidekiq.gemspec +1 -1
- data/test/test_api.rb +19 -10
- data/test/test_cli.rb +1 -1
- data/test/test_client.rb +1 -1
- data/test/test_exception_handler.rb +1 -1
- data/test/test_extensions.rb +1 -1
- data/test/test_fetch.rb +1 -1
- data/test/test_logging.rb +34 -0
- data/test/test_manager.rb +2 -2
- data/test/test_middleware.rb +1 -1
- data/test/test_processor.rb +1 -1
- data/test/test_redis_connection.rb +1 -1
- data/test/test_retry.rb +4 -2
- data/test/test_scheduled.rb +1 -1
- data/test/test_scheduling.rb +1 -1
- data/test/test_sidekiq.rb +13 -1
- data/test/test_testing.rb +1 -1
- data/test/test_testing_fake.rb +1 -1
- data/test/test_testing_inline.rb +1 -1
- data/test/test_web.rb +52 -9
- data/test/test_worker_generator.rb +1 -1
- data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -0
- data/web/assets/javascripts/locales/{jquery.timeago.zh-CN.js → jquery.timeago.zh-cn.js} +0 -0
- data/web/assets/javascripts/locales/{jquery.timeago.zh-TW.js → jquery.timeago.zh-tw.js} +0 -0
- data/web/assets/stylesheets/application.css +1 -4
- data/web/locales/ru.yml +6 -0
- data/web/views/_footer.erb +1 -1
- data/web/views/_summary.erb +1 -1
- data/web/views/busy.erb +3 -4
- data/web/views/dashboard.erb +1 -1
- metadata +10 -7
data/lib/sidekiq/cli.rb
CHANGED
@@ -107,17 +107,6 @@ module Sidekiq
|
|
107
107
|
sss }
|
108
108
|
end
|
109
109
|
|
110
|
-
private
|
111
|
-
|
112
|
-
def print_banner
|
113
|
-
# Print logo and banner for development
|
114
|
-
if environment == 'development' && $stdout.tty?
|
115
|
-
puts "\e[#{31}m"
|
116
|
-
puts Sidekiq::CLI.banner
|
117
|
-
puts "\e[0m"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
110
|
def handle_signal(sig)
|
122
111
|
Sidekiq.logger.debug "Got #{sig} signal"
|
123
112
|
case sig
|
@@ -149,6 +138,17 @@ module Sidekiq
|
|
149
138
|
end
|
150
139
|
end
|
151
140
|
|
141
|
+
private
|
142
|
+
|
143
|
+
def print_banner
|
144
|
+
# Print logo and banner for development
|
145
|
+
if environment == 'development' && $stdout.tty?
|
146
|
+
puts "\e[#{31}m"
|
147
|
+
puts Sidekiq::CLI.banner
|
148
|
+
puts "\e[0m"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
152
|
def load_celluloid
|
153
153
|
raise "Celluloid cannot be required until here, or it will break Sidekiq's daemonization" if defined?(::Celluloid) && options[:daemon]
|
154
154
|
|
data/lib/sidekiq/client.rb
CHANGED
@@ -55,7 +55,7 @@ module Sidekiq
|
|
55
55
|
# All options must be strings, not symbols. NB: because we are serializing to JSON, all
|
56
56
|
# symbols in 'args' will be converted to strings.
|
57
57
|
#
|
58
|
-
# Returns
|
58
|
+
# Returns a unique Job ID. If middleware stops the job, nil will be returned instead.
|
59
59
|
#
|
60
60
|
# Example:
|
61
61
|
# push('queue' => 'my_queue', 'class' => MyWorker, 'args' => ['foo', 1, :bat => 'bar'])
|
@@ -64,9 +64,10 @@ module Sidekiq
|
|
64
64
|
normed = normalize_item(item)
|
65
65
|
payload = process_single(item['class'], normed)
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
if payload
|
68
|
+
raw_push([payload])
|
69
|
+
payload['jid']
|
70
|
+
end
|
70
71
|
end
|
71
72
|
|
72
73
|
##
|
@@ -80,9 +81,8 @@ module Sidekiq
|
|
80
81
|
# is run through the client middleware pipeline and each job gets its own Job ID
|
81
82
|
# as normal.
|
82
83
|
#
|
83
|
-
# Returns an array of the of pushed jobs' jids
|
84
|
-
#
|
85
|
-
# or more jobs.
|
84
|
+
# Returns an array of the of pushed jobs' jids. The number of jobs pushed can be less
|
85
|
+
# than the number given if the middleware stopped processing for one or more jobs.
|
86
86
|
def push_bulk(items)
|
87
87
|
normed = normalize_item(items)
|
88
88
|
payloads = items['args'].map do |args|
|
@@ -90,9 +90,8 @@ module Sidekiq
|
|
90
90
|
process_single(items['class'], normed.merge('args' => args, 'jid' => SecureRandom.hex(12), 'enqueued_at' => Time.now.to_f))
|
91
91
|
end.compact
|
92
92
|
|
93
|
-
|
94
|
-
|
95
|
-
pushed ? payloads.collect { |payload| payload['jid'] } : nil
|
93
|
+
raw_push(payloads) if !payloads.empty?
|
94
|
+
payloads.collect { |payload| payload['jid'] }
|
96
95
|
end
|
97
96
|
|
98
97
|
# Allows sharding of jobs across any number of Redis instances. All jobs
|
@@ -160,7 +159,7 @@ module Sidekiq
|
|
160
159
|
ts = (int < 1_000_000_000 ? now + int : int)
|
161
160
|
|
162
161
|
item = { 'class' => klass, 'args' => args, 'at' => ts, 'queue' => queue }
|
163
|
-
item.delete('at') if ts <= now
|
162
|
+
item.delete('at'.freeze) if ts <= now
|
164
163
|
|
165
164
|
klass.client_push(item)
|
166
165
|
end
|
@@ -186,14 +185,14 @@ module Sidekiq
|
|
186
185
|
|
187
186
|
def atomic_push(conn, payloads)
|
188
187
|
if payloads.first['at']
|
189
|
-
conn.zadd('schedule', payloads.map do |hash|
|
190
|
-
at = hash.delete('at').to_s
|
188
|
+
conn.zadd('schedule'.freeze, payloads.map do |hash|
|
189
|
+
at = hash.delete('at'.freeze).to_s
|
191
190
|
[at, Sidekiq.dump_json(hash)]
|
192
191
|
end)
|
193
192
|
else
|
194
193
|
q = payloads.first['queue']
|
195
194
|
to_push = payloads.map { |entry| Sidekiq.dump_json(entry) }
|
196
|
-
conn.sadd('queues', q)
|
195
|
+
conn.sadd('queues'.freeze, q)
|
197
196
|
conn.lpush("queue:#{q}", to_push)
|
198
197
|
end
|
199
198
|
end
|
@@ -17,7 +17,11 @@ module Sidekiq
|
|
17
17
|
msg = target.public_send(method_name, *args)
|
18
18
|
# The email method can return nil, which causes ActionMailer to return
|
19
19
|
# an undeliverable empty message.
|
20
|
-
|
20
|
+
if msg
|
21
|
+
deliver(msg)
|
22
|
+
else
|
23
|
+
raise "#{target.name}##{method_name} returned an undeliverable mail object"
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
27
|
private
|
data/lib/sidekiq/launcher.rb
CHANGED
@@ -27,7 +27,9 @@ module Sidekiq
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def actor_died(actor, reason)
|
30
|
-
|
30
|
+
# https://github.com/mperham/sidekiq/issues/2057#issuecomment-66485477
|
31
|
+
return if @done || !reason
|
32
|
+
|
31
33
|
Sidekiq.logger.warn("Sidekiq died due to the following error, cannot recover, process exiting")
|
32
34
|
handle_exception(reason)
|
33
35
|
exit(1)
|
@@ -73,6 +75,7 @@ module Sidekiq
|
|
73
75
|
'concurrency' => @options[:concurrency],
|
74
76
|
'queues' => @options[:queues].uniq,
|
75
77
|
'labels' => Sidekiq.options[:labels],
|
78
|
+
'identity' => identity,
|
76
79
|
}
|
77
80
|
# this data doesn't change so dump it to a string
|
78
81
|
# now so we don't need to dump it every heartbeat.
|
data/lib/sidekiq/logging.rb
CHANGED
@@ -5,6 +5,8 @@ module Sidekiq
|
|
5
5
|
module Logging
|
6
6
|
|
7
7
|
class Pretty < Logger::Formatter
|
8
|
+
SPACE = " "
|
9
|
+
|
8
10
|
# Provide a call() method that returns the formatted message.
|
9
11
|
def call(severity, time, program_name, message)
|
10
12
|
"#{time.utc.iso8601(3)} #{::Process.pid} TID-#{Thread.current.object_id.to_s(36)}#{context} #{severity}: #{message}\n"
|
@@ -12,17 +14,16 @@ module Sidekiq
|
|
12
14
|
|
13
15
|
def context
|
14
16
|
c = Thread.current[:sidekiq_context]
|
15
|
-
|
17
|
+
" #{c.join(SPACE)}" if c && c.any?
|
16
18
|
end
|
17
19
|
end
|
18
20
|
|
19
21
|
def self.with_context(msg)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
22
|
+
Thread.current[:sidekiq_context] ||= []
|
23
|
+
Thread.current[:sidekiq_context] << msg
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
Thread.current[:sidekiq_context].pop
|
26
27
|
end
|
27
28
|
|
28
29
|
def self.initialize_logger(log_target = STDOUT)
|
data/lib/sidekiq/manager.rb
CHANGED
@@ -21,6 +21,7 @@ module Sidekiq
|
|
21
21
|
attr_accessor :fetcher
|
22
22
|
|
23
23
|
SPIN_TIME_FOR_GRACEFUL_SHUTDOWN = 1
|
24
|
+
JVM_RESERVED_SIGNALS = ['USR1', 'USR2'] # Don't Process#kill if we get these signals via the API
|
24
25
|
|
25
26
|
def initialize(condvar, options={})
|
26
27
|
logger.debug { options.inspect }
|
@@ -47,7 +48,7 @@ module Sidekiq
|
|
47
48
|
|
48
49
|
@done = true
|
49
50
|
|
50
|
-
logger.info { "
|
51
|
+
logger.info { "Terminating #{@ready.size} quiet workers" }
|
51
52
|
@ready.each { |x| x.terminate if x.alive? }
|
52
53
|
@ready.clear
|
53
54
|
|
@@ -159,7 +160,13 @@ module Sidekiq
|
|
159
160
|
end
|
160
161
|
end
|
161
162
|
|
162
|
-
|
163
|
+
return unless msg
|
164
|
+
|
165
|
+
if JVM_RESERVED_SIGNALS.include?(msg)
|
166
|
+
Sidekiq::CLI.instance.handle_signal(msg)
|
167
|
+
else
|
168
|
+
::Process.kill(msg, $$)
|
169
|
+
end
|
163
170
|
rescue => e
|
164
171
|
# ignore all redis/network issues
|
165
172
|
logger.error("heartbeat: #{e.message}")
|
@@ -4,7 +4,7 @@ module Sidekiq
|
|
4
4
|
class Logging
|
5
5
|
|
6
6
|
def call(worker, item, queue)
|
7
|
-
Sidekiq::Logging.with_context("#{worker.class.to_s} JID-#{item['jid']}") do
|
7
|
+
Sidekiq::Logging.with_context("#{worker.class.to_s} JID-#{item['jid']}#{" BID-#{item['bid']}" if item['bid']}") do
|
8
8
|
begin
|
9
9
|
start = Time.now
|
10
10
|
logger.info { "start" }
|
@@ -114,10 +114,10 @@ module Sidekiq
|
|
114
114
|
|
115
115
|
if msg['backtrace'] == true
|
116
116
|
msg['error_backtrace'] = exception.backtrace
|
117
|
-
elsif msg['backtrace']
|
117
|
+
elsif !msg['backtrace']
|
118
118
|
# do nothing
|
119
119
|
elsif msg['backtrace'].to_i != 0
|
120
|
-
msg['error_backtrace'] = exception.backtrace[0
|
120
|
+
msg['error_backtrace'] = exception.backtrace[0...msg['backtrace'].to_i]
|
121
121
|
end
|
122
122
|
|
123
123
|
if count < max_retry_attempts
|
@@ -143,7 +143,7 @@ module Sidekiq
|
|
143
143
|
worker.sidekiq_retries_exhausted_block.call(msg)
|
144
144
|
end
|
145
145
|
rescue => e
|
146
|
-
handle_exception(e, { :
|
146
|
+
handle_exception(e, { context: "Error calling retries_exhausted for #{worker.class}", job: msg })
|
147
147
|
end
|
148
148
|
|
149
149
|
send_to_morgue(msg) unless msg['dead'] == false
|
@@ -183,7 +183,7 @@ module Sidekiq
|
|
183
183
|
begin
|
184
184
|
worker.sidekiq_retry_in_block.call(count)
|
185
185
|
rescue Exception => e
|
186
|
-
handle_exception(e, { :
|
186
|
+
handle_exception(e, { context: "Failure scheduling retry using the defined `sidekiq_retry_in` in #{worker.class.name}, falling back to default" })
|
187
187
|
nil
|
188
188
|
end
|
189
189
|
end
|
data/lib/sidekiq/processor.rb
CHANGED
@@ -98,26 +98,26 @@ module Sidekiq
|
|
98
98
|
yield
|
99
99
|
rescue Exception
|
100
100
|
retry_and_suppress_exceptions do
|
101
|
+
failed = "stat:failed:#{Time.now.utc.to_date}"
|
101
102
|
Sidekiq.redis do |conn|
|
102
|
-
|
103
|
-
result = conn.multi do
|
103
|
+
conn.multi do
|
104
104
|
conn.incrby("stat:failed", 1)
|
105
105
|
conn.incrby(failed, 1)
|
106
|
+
conn.expire(failed, STATS_TIMEOUT)
|
106
107
|
end
|
107
|
-
conn.expire(failed, STATS_TIMEOUT) if result.last == 1
|
108
108
|
end
|
109
109
|
end
|
110
110
|
raise
|
111
111
|
ensure
|
112
112
|
retry_and_suppress_exceptions do
|
113
|
+
processed = "stat:processed:#{Time.now.utc.to_date}"
|
113
114
|
Sidekiq.redis do |conn|
|
114
|
-
|
115
|
-
result = conn.multi do
|
115
|
+
conn.multi do
|
116
116
|
conn.hdel("#{identity}:workers", thread_identity)
|
117
117
|
conn.incrby("stat:processed", 1)
|
118
118
|
conn.incrby(processed, 1)
|
119
|
+
conn.expire(processed, STATS_TIMEOUT)
|
119
120
|
end
|
120
|
-
conn.expire(processed, STATS_TIMEOUT) if result.last == 1
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
data/lib/sidekiq/testing.rb
CHANGED
@@ -7,12 +7,12 @@ module Sidekiq
|
|
7
7
|
class << self
|
8
8
|
attr_accessor :__test_mode
|
9
9
|
|
10
|
-
def __set_test_mode(mode
|
11
|
-
if
|
10
|
+
def __set_test_mode(mode)
|
11
|
+
if block_given?
|
12
12
|
current_mode = self.__test_mode
|
13
13
|
begin
|
14
14
|
self.__test_mode = mode
|
15
|
-
|
15
|
+
yield
|
16
16
|
ensure
|
17
17
|
self.__test_mode = current_mode
|
18
18
|
end
|
@@ -66,12 +66,11 @@ module Sidekiq
|
|
66
66
|
end
|
67
67
|
true
|
68
68
|
elsif Sidekiq::Testing.inline?
|
69
|
-
payloads.each do |
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
worker.perform(*marshalled['args'])
|
69
|
+
payloads.each do |job|
|
70
|
+
job['jid'] ||= SecureRandom.hex(12)
|
71
|
+
klass = job['class'].constantize
|
72
|
+
klass.jobs.unshift Sidekiq.load_json(Sidekiq.dump_json(job))
|
73
|
+
klass.perform_one
|
75
74
|
end
|
76
75
|
true
|
77
76
|
else
|
data/lib/sidekiq/util.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'socket'
|
2
|
+
require 'securerandom'
|
2
3
|
require 'sidekiq/exception_handler'
|
3
4
|
require 'sidekiq/core_ext'
|
4
5
|
|
@@ -14,7 +15,7 @@ module Sidekiq
|
|
14
15
|
def watchdog(last_words)
|
15
16
|
yield
|
16
17
|
rescue Exception => ex
|
17
|
-
handle_exception(ex, { :
|
18
|
+
handle_exception(ex, { context: last_words })
|
18
19
|
raise ex
|
19
20
|
end
|
20
21
|
|
@@ -30,8 +31,12 @@ module Sidekiq
|
|
30
31
|
ENV['DYNO'] || Socket.gethostname
|
31
32
|
end
|
32
33
|
|
34
|
+
def process_nonce
|
35
|
+
@@process_nonce ||= SecureRandom.hex(6)
|
36
|
+
end
|
37
|
+
|
33
38
|
def identity
|
34
|
-
@@identity ||= "#{hostname}:#{$$}"
|
39
|
+
@@identity ||= "#{hostname}:#{$$}:#{process_nonce}"
|
35
40
|
end
|
36
41
|
|
37
42
|
def fire_event(event)
|
@@ -39,7 +44,7 @@ module Sidekiq
|
|
39
44
|
begin
|
40
45
|
block.call
|
41
46
|
rescue => ex
|
42
|
-
handle_exception(ex, { :
|
47
|
+
handle_exception(ex, { event: event })
|
43
48
|
end
|
44
49
|
end
|
45
50
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -45,12 +45,12 @@ module Sidekiq
|
|
45
45
|
end
|
46
46
|
|
47
47
|
post "/busy" do
|
48
|
-
if params['
|
49
|
-
p = Sidekiq::Process.new('
|
48
|
+
if params['identity']
|
49
|
+
p = Sidekiq::Process.new('identity' => params['identity'])
|
50
50
|
p.quiet! if params[:quiet]
|
51
51
|
p.stop! if params[:stop]
|
52
52
|
else
|
53
|
-
|
53
|
+
processes.each do |pro|
|
54
54
|
pro.quiet! if params[:quiet]
|
55
55
|
pro.stop! if params[:stop]
|
56
56
|
end
|
@@ -69,7 +69,7 @@ module Sidekiq
|
|
69
69
|
@name = params[:name]
|
70
70
|
@queue = Sidekiq::Queue.new(@name)
|
71
71
|
(@current_page, @total_size, @messages) = page("queue:#{@name}", params[:page], @count)
|
72
|
-
@messages = @messages.map {|msg| Sidekiq::Job.new(msg, @name) }
|
72
|
+
@messages = @messages.map { |msg| Sidekiq::Job.new(msg, @name) }
|
73
73
|
erb :queue
|
74
74
|
end
|
75
75
|
|
@@ -85,8 +85,8 @@ module Sidekiq
|
|
85
85
|
|
86
86
|
get '/morgue' do
|
87
87
|
@count = (params[:count] || 25).to_i
|
88
|
-
(@current_page, @total_size, @dead) = page("dead", params[:page], @count, :
|
89
|
-
@dead = @dead.map {|msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
88
|
+
(@current_page, @total_size, @dead) = page("dead", params[:page], @count, reverse: true)
|
89
|
+
@dead = @dead.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
90
90
|
erb :morgue
|
91
91
|
end
|
92
92
|
|
@@ -128,7 +128,7 @@ module Sidekiq
|
|
128
128
|
get '/retries' do
|
129
129
|
@count = (params[:count] || 25).to_i
|
130
130
|
(@current_page, @total_size, @retries) = page("retry", params[:page], @count)
|
131
|
-
@retries = @retries.map {|msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
131
|
+
@retries = @retries.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
132
132
|
erb :retries
|
133
133
|
end
|
134
134
|
|
@@ -167,7 +167,7 @@ module Sidekiq
|
|
167
167
|
get '/scheduled' do
|
168
168
|
@count = (params[:count] || 25).to_i
|
169
169
|
(@current_page, @total_size, @scheduled) = page("schedule", params[:page], @count)
|
170
|
-
@scheduled = @scheduled.map {|msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
170
|
+
@scheduled = @scheduled.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
171
171
|
erb :scheduled
|
172
172
|
end
|
173
173
|
|
@@ -205,24 +205,37 @@ module Sidekiq
|
|
205
205
|
REDIS_KEYS = %w(redis_version uptime_in_days connected_clients used_memory_human used_memory_peak_human)
|
206
206
|
|
207
207
|
get '/dashboard/stats' do
|
208
|
+
redirect "#{root_path}stats"
|
209
|
+
end
|
210
|
+
|
211
|
+
get '/stats' do
|
208
212
|
sidekiq_stats = Sidekiq::Stats.new
|
209
|
-
|
210
|
-
redis_stats = redis_info.select{ |k, v| REDIS_KEYS.include? k }
|
213
|
+
redis_stats = redis_info.select { |k, v| REDIS_KEYS.include? k }
|
211
214
|
|
212
215
|
content_type :json
|
213
|
-
Sidekiq.dump_json(
|
216
|
+
Sidekiq.dump_json(
|
214
217
|
sidekiq: {
|
215
|
-
processed:
|
216
|
-
failed:
|
217
|
-
busy:
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
218
|
+
processed: sidekiq_stats.processed,
|
219
|
+
failed: sidekiq_stats.failed,
|
220
|
+
busy: sidekiq_stats.workers_size,
|
221
|
+
processes: sidekiq_stats.processes_size,
|
222
|
+
enqueued: sidekiq_stats.enqueued,
|
223
|
+
scheduled: sidekiq_stats.scheduled_size,
|
224
|
+
retries: sidekiq_stats.retry_size,
|
225
|
+
dead: sidekiq_stats.dead_size,
|
226
|
+
default_latency: sidekiq_stats.default_queue_latency
|
223
227
|
},
|
224
228
|
redis: redis_stats
|
225
|
-
|
229
|
+
)
|
230
|
+
end
|
231
|
+
|
232
|
+
get '/stats/queues' do
|
233
|
+
queue_stats = Sidekiq::Stats::Queues.new
|
234
|
+
|
235
|
+
content_type :json
|
236
|
+
Sidekiq.dump_json(
|
237
|
+
queue_stats.lengths
|
238
|
+
)
|
226
239
|
end
|
227
240
|
|
228
241
|
private
|