sidekiq 5.2.10 → 6.0.0.pre1
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/.standard.yml +20 -0
- data/.travis.yml +5 -2
- data/6.0-Upgrade.md +58 -0
- data/Changes.md +21 -16
- data/Gemfile +15 -10
- data/Rakefile +5 -4
- data/bin/sidekiqctl +1 -10
- data/lib/generators/sidekiq/worker_generator.rb +12 -14
- data/lib/sidekiq/api.rb +133 -148
- data/lib/sidekiq/cli.rb +95 -147
- data/lib/sidekiq/client.rb +44 -45
- data/lib/sidekiq/ctl.rb +35 -109
- data/lib/sidekiq/delay.rb +5 -6
- data/lib/sidekiq/exception_handler.rb +10 -12
- data/lib/sidekiq/extensions/action_mailer.rb +10 -20
- data/lib/sidekiq/extensions/active_record.rb +9 -7
- data/lib/sidekiq/extensions/class_methods.rb +9 -7
- data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
- data/lib/sidekiq/fetch.rb +5 -6
- data/lib/sidekiq/job_logger.rb +37 -7
- data/lib/sidekiq/job_retry.rb +45 -58
- data/lib/sidekiq/launcher.rb +59 -48
- data/lib/sidekiq/logger.rb +69 -0
- data/lib/sidekiq/manager.rb +6 -8
- data/lib/sidekiq/middleware/chain.rb +2 -1
- data/lib/sidekiq/middleware/i18n.rb +5 -7
- data/lib/sidekiq/paginator.rb +11 -12
- data/lib/sidekiq/processor.rb +42 -45
- data/lib/sidekiq/rails.rb +2 -26
- data/lib/sidekiq/redis_connection.rb +31 -37
- data/lib/sidekiq/scheduled.rb +17 -19
- data/lib/sidekiq/testing/inline.rb +2 -1
- data/lib/sidekiq/testing.rb +22 -23
- data/lib/sidekiq/util.rb +18 -15
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +59 -59
- data/lib/sidekiq/web/helpers.rb +66 -67
- data/lib/sidekiq/web/router.rb +17 -14
- data/lib/sidekiq/web.rb +36 -44
- data/lib/sidekiq/worker.rb +12 -13
- data/lib/sidekiq.rb +53 -42
- data/sidekiq.gemspec +7 -7
- metadata +20 -32
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -23
data/lib/sidekiq/ctl.rb
CHANGED
@@ -1,109 +1,36 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "fileutils"
|
4
|
+
require "sidekiq/api"
|
5
5
|
|
6
6
|
class Sidekiq::Ctl
|
7
|
-
|
8
|
-
CMD = File.basename($0)
|
7
|
+
CMD = File.basename($PROGRAM_NAME)
|
9
8
|
|
10
|
-
attr_reader :stage
|
9
|
+
attr_reader :stage
|
11
10
|
|
12
11
|
def self.print_usage
|
13
12
|
puts "#{CMD} - control Sidekiq from the command line."
|
14
13
|
puts
|
15
|
-
puts "Usage: #{CMD}
|
16
|
-
puts " #{CMD} stop <pidfile> <kill_timeout>"
|
17
|
-
puts " #{CMD} status <section>"
|
18
|
-
puts
|
19
|
-
puts " <pidfile> is path to a pidfile"
|
20
|
-
puts " <kill_timeout> is number of seconds to wait until Sidekiq exits"
|
21
|
-
puts " (default: #{Sidekiq::Ctl::DEFAULT_KILL_TIMEOUT}), after which Sidekiq will be KILL'd"
|
14
|
+
puts "Usage: #{CMD} status <section>"
|
22
15
|
puts
|
23
16
|
puts " <section> (optional) view a specific section of the status output"
|
24
|
-
puts " Valid sections are: #{Sidekiq::Ctl::Status::VALID_SECTIONS.join(
|
25
|
-
puts
|
26
|
-
puts "Be sure to set the kill_timeout LONGER than Sidekiq's -t timeout. If you want"
|
27
|
-
puts "to wait 60 seconds for jobs to finish, use `sidekiq -t 60` and `sidekiqctl stop"
|
28
|
-
puts " path_to_pidfile 61`"
|
17
|
+
puts " Valid sections are: #{Sidekiq::Ctl::Status::VALID_SECTIONS.join(", ")}"
|
29
18
|
puts
|
30
19
|
end
|
31
20
|
|
32
|
-
def initialize(stage, pidfile, timeout)
|
33
|
-
@stage = stage
|
34
|
-
@pidfile = pidfile
|
35
|
-
@kill_timeout = timeout
|
36
|
-
|
37
|
-
done('No pidfile given', :error) if !pidfile
|
38
|
-
done("Pidfile #{pidfile} does not exist", :warn) if !File.exist?(pidfile)
|
39
|
-
done('Invalid pidfile content', :error) if pid == 0
|
40
|
-
|
41
|
-
fetch_process
|
42
|
-
|
43
|
-
begin
|
44
|
-
send(stage)
|
45
|
-
rescue NoMethodError
|
46
|
-
done "Invalid command: #{stage}", :error
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def fetch_process
|
51
|
-
Process.kill(0, pid)
|
52
|
-
rescue Errno::ESRCH
|
53
|
-
done "Process doesn't exist", :error
|
54
|
-
# We were not allowed to send a signal, but the process must have existed
|
55
|
-
# when Process.kill() was called.
|
56
|
-
rescue Errno::EPERM
|
57
|
-
return pid
|
58
|
-
end
|
59
|
-
|
60
|
-
def done(msg, error = nil)
|
61
|
-
puts msg
|
62
|
-
exit(exit_signal(error))
|
63
|
-
end
|
64
|
-
|
65
|
-
def exit_signal(error)
|
66
|
-
(error == :error) ? 1 : 0
|
67
|
-
end
|
68
|
-
|
69
|
-
def pid
|
70
|
-
@pid ||= File.read(pidfile).to_i
|
71
|
-
end
|
72
|
-
|
73
|
-
def quiet
|
74
|
-
`kill -TSTP #{pid}`
|
75
|
-
end
|
76
|
-
|
77
|
-
def stop
|
78
|
-
`kill -TERM #{pid}`
|
79
|
-
kill_timeout.times do
|
80
|
-
begin
|
81
|
-
Process.kill(0, pid)
|
82
|
-
rescue Errno::ESRCH
|
83
|
-
FileUtils.rm_f pidfile
|
84
|
-
done 'Sidekiq shut down gracefully.'
|
85
|
-
rescue Errno::EPERM
|
86
|
-
done 'Not permitted to shut down Sidekiq.'
|
87
|
-
end
|
88
|
-
sleep 1
|
89
|
-
end
|
90
|
-
`kill -9 #{pid}`
|
91
|
-
FileUtils.rm_f pidfile
|
92
|
-
done 'Sidekiq shut down forcefully.'
|
93
|
-
end
|
94
|
-
alias_method :shutdown, :stop
|
95
|
-
|
96
21
|
class Status
|
97
22
|
VALID_SECTIONS = %w[all version overview processes queues]
|
23
|
+
COL_PAD = 2
|
24
|
+
|
98
25
|
def display(section = nil)
|
99
|
-
section ||=
|
26
|
+
section ||= "all"
|
100
27
|
unless VALID_SECTIONS.include? section
|
101
28
|
puts "I don't know how to check the status of '#{section}'!"
|
102
|
-
puts "Try one of these: #{VALID_SECTIONS.join(
|
29
|
+
puts "Try one of these: #{VALID_SECTIONS.join(", ")}"
|
103
30
|
return
|
104
31
|
end
|
105
32
|
send(section)
|
106
|
-
rescue
|
33
|
+
rescue => e
|
107
34
|
puts "Couldn't get status: #{e}"
|
108
35
|
end
|
109
36
|
|
@@ -123,7 +50,7 @@ class Sidekiq::Ctl
|
|
123
50
|
end
|
124
51
|
|
125
52
|
def overview
|
126
|
-
puts
|
53
|
+
puts "---- Overview ----"
|
127
54
|
puts " Processed: #{delimit stats.processed}"
|
128
55
|
puts " Failed: #{delimit stats.failed}"
|
129
56
|
puts " Busy: #{delimit stats.workers_size}"
|
@@ -136,21 +63,20 @@ class Sidekiq::Ctl
|
|
136
63
|
def processes
|
137
64
|
puts "---- Processes (#{process_set.size}) ----"
|
138
65
|
process_set.each_with_index do |process, index|
|
139
|
-
puts "#{process[
|
140
|
-
puts " Started: #{Time.at(process[
|
141
|
-
puts " Threads: #{process[
|
142
|
-
puts " Queues: #{split_multiline(process[
|
143
|
-
puts
|
66
|
+
puts "#{process["identity"]} #{tags_for(process)}"
|
67
|
+
puts " Started: #{Time.at(process["started_at"])} (#{time_ago(process["started_at"])})"
|
68
|
+
puts " Threads: #{process["concurrency"]} (#{process["busy"]} busy)"
|
69
|
+
puts " Queues: #{split_multiline(process["queues"].sort, pad: 11)}"
|
70
|
+
puts "" unless (index + 1) == process_set.size
|
144
71
|
end
|
145
72
|
end
|
146
73
|
|
147
|
-
COL_PAD = 2
|
148
74
|
def queues
|
149
75
|
puts "---- Queues (#{queue_data.size}) ----"
|
150
76
|
columns = {
|
151
|
-
name: [:ljust, ([
|
152
|
-
size: [:rjust, ([
|
153
|
-
latency: [:rjust, ([
|
77
|
+
name: [:ljust, (["name"] + queue_data.map(&:name)).map(&:length).max + COL_PAD],
|
78
|
+
size: [:rjust, (["size"] + queue_data.map(&:size)).map(&:length).max + COL_PAD],
|
79
|
+
latency: [:rjust, (["latency"] + queue_data.map(&:latency)).map(&:length).max + COL_PAD],
|
154
80
|
}
|
155
81
|
columns.each { |col, (dir, width)| print col.to_s.upcase.public_send(dir, width) }
|
156
82
|
puts
|
@@ -165,21 +91,21 @@ class Sidekiq::Ctl
|
|
165
91
|
private
|
166
92
|
|
167
93
|
def delimit(number)
|
168
|
-
number.to_s.reverse.scan(/.{1,3}/).join(
|
94
|
+
number.to_s.reverse.scan(/.{1,3}/).join(",").reverse
|
169
95
|
end
|
170
96
|
|
171
97
|
def split_multiline(values, opts = {})
|
172
|
-
return
|
98
|
+
return "none" unless values
|
173
99
|
pad = opts[:pad] || 0
|
174
100
|
max_length = opts[:max_length] || (80 - pad)
|
175
101
|
out = []
|
176
|
-
line =
|
102
|
+
line = ""
|
177
103
|
values.each do |value|
|
178
104
|
if (line.length + value.length) > max_length
|
179
105
|
out << line
|
180
|
-
line =
|
106
|
+
line = " " * pad
|
181
107
|
end
|
182
|
-
line << value +
|
108
|
+
line << value + ", "
|
183
109
|
end
|
184
110
|
out << line[0..-3]
|
185
111
|
out.join("\n")
|
@@ -187,27 +113,27 @@ class Sidekiq::Ctl
|
|
187
113
|
|
188
114
|
def tags_for(process)
|
189
115
|
tags = [
|
190
|
-
process[
|
191
|
-
process[
|
192
|
-
(process[
|
116
|
+
process["tag"],
|
117
|
+
process["labels"],
|
118
|
+
(process["quiet"] == "true" ? "quiet" : nil),
|
193
119
|
].flatten.compact
|
194
|
-
tags.any? ? "[#{tags.join(
|
120
|
+
tags.any? ? "[#{tags.join("] [")}]" : nil
|
195
121
|
end
|
196
122
|
|
197
123
|
def time_ago(timestamp)
|
198
124
|
seconds = Time.now - Time.at(timestamp)
|
199
|
-
return
|
200
|
-
return
|
125
|
+
return "just now" if seconds < 60
|
126
|
+
return "a minute ago" if seconds < 120
|
201
127
|
return "#{seconds.floor / 60} minutes ago" if seconds < 3600
|
202
|
-
return
|
128
|
+
return "an hour ago" if seconds < 7200
|
203
129
|
"#{seconds.floor / 60 / 60} hours ago"
|
204
130
|
end
|
205
131
|
|
206
132
|
QUEUE_STRUCT = Struct.new(:name, :size, :latency)
|
207
133
|
def queue_data
|
208
|
-
@queue_data ||= Sidekiq::Queue.all.map
|
209
|
-
QUEUE_STRUCT.new(q.name, q.size.to_s, sprintf(
|
210
|
-
|
134
|
+
@queue_data ||= Sidekiq::Queue.all.map { |q|
|
135
|
+
QUEUE_STRUCT.new(q.name, q.size.to_s, sprintf("%#.2f", q.latency))
|
136
|
+
}
|
211
137
|
end
|
212
138
|
|
213
139
|
def process_set
|
data/lib/sidekiq/delay.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Sidekiq
|
3
4
|
module Extensions
|
4
|
-
|
5
5
|
def self.enable_delay!
|
6
6
|
if defined?(::ActiveSupport)
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require "sidekiq/extensions/active_record"
|
8
|
+
require "sidekiq/extensions/action_mailer"
|
9
9
|
|
10
10
|
# Need to patch Psych so it can autoload classes whose names are serialized
|
11
11
|
# in the delayed YAML.
|
@@ -19,7 +19,7 @@ module Sidekiq
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
require
|
22
|
+
require "sidekiq/extensions/class_methods"
|
23
23
|
Module.__send__(:include, Sidekiq::Extensions::Klass)
|
24
24
|
end
|
25
25
|
|
@@ -27,7 +27,7 @@ module Sidekiq
|
|
27
27
|
def resolve_class(klass_name)
|
28
28
|
return nil if !klass_name || klass_name.empty?
|
29
29
|
# constantize
|
30
|
-
names = klass_name.split(
|
30
|
+
names = klass_name.split("::")
|
31
31
|
names.shift if names.empty? || names.first.empty?
|
32
32
|
|
33
33
|
names.inject(Object) do |constant, name|
|
@@ -39,4 +39,3 @@ module Sidekiq
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "sidekiq"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
module ExceptionHandler
|
6
|
-
|
7
7
|
class Logger
|
8
|
-
def call(ex,
|
9
|
-
Sidekiq.logger.warn(Sidekiq.dump_json(
|
8
|
+
def call(ex, ctx)
|
9
|
+
Sidekiq.logger.warn(Sidekiq.dump_json(ctx)) unless ctx.empty?
|
10
10
|
Sidekiq.logger.warn("#{ex.class.name}: #{ex.message}")
|
11
11
|
Sidekiq.logger.warn(ex.backtrace.join("\n")) unless ex.backtrace.nil?
|
12
12
|
end
|
@@ -14,15 +14,13 @@ module Sidekiq
|
|
14
14
|
Sidekiq.error_handlers << Sidekiq::ExceptionHandler::Logger.new
|
15
15
|
end
|
16
16
|
|
17
|
-
def handle_exception(ex,
|
17
|
+
def handle_exception(ex, ctx = {})
|
18
18
|
Sidekiq.error_handlers.each do |handler|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Sidekiq.logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
|
25
|
-
end
|
19
|
+
handler.call(ex, ctx)
|
20
|
+
rescue => ex
|
21
|
+
Sidekiq.logger.error "!!! ERROR HANDLER THREW AN ERROR !!!"
|
22
|
+
Sidekiq.logger.error ex
|
23
|
+
Sidekiq.logger.error ex.backtrace.join("\n") unless ex.backtrace.nil?
|
26
24
|
end
|
27
25
|
end
|
28
26
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "sidekiq/extensions/generic_proxy"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
module Extensions
|
@@ -19,39 +20,28 @@ module Sidekiq
|
|
19
20
|
# The email method can return nil, which causes ActionMailer to return
|
20
21
|
# an undeliverable empty message.
|
21
22
|
if msg
|
22
|
-
deliver(msg)
|
23
|
-
else
|
24
|
-
raise "#{target.name}##{method_name} returned an undeliverable mail object"
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def deliver(msg)
|
31
|
-
if msg.respond_to?(:deliver_now)
|
32
|
-
# Rails 4.2/5.0
|
33
23
|
msg.deliver_now
|
34
24
|
else
|
35
|
-
#
|
36
|
-
msg.deliver
|
25
|
+
raise "#{target.name}##{method_name} returned an undeliverable mail object"
|
37
26
|
end
|
38
27
|
end
|
39
28
|
end
|
40
29
|
|
41
30
|
module ActionMailer
|
42
|
-
def sidekiq_delay(options={})
|
31
|
+
def sidekiq_delay(options = {})
|
43
32
|
Proxy.new(DelayedMailer, self, options)
|
44
33
|
end
|
45
|
-
|
46
|
-
|
34
|
+
|
35
|
+
def sidekiq_delay_for(interval, options = {})
|
36
|
+
Proxy.new(DelayedMailer, self, options.merge("at" => Time.now.to_f + interval.to_f))
|
47
37
|
end
|
48
|
-
|
49
|
-
|
38
|
+
|
39
|
+
def sidekiq_delay_until(timestamp, options = {})
|
40
|
+
Proxy.new(DelayedMailer, self, options.merge("at" => timestamp.to_f))
|
50
41
|
end
|
51
42
|
alias_method :delay, :sidekiq_delay
|
52
43
|
alias_method :delay_for, :sidekiq_delay_for
|
53
44
|
alias_method :delay_until, :sidekiq_delay_until
|
54
45
|
end
|
55
|
-
|
56
46
|
end
|
57
47
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "sidekiq/extensions/generic_proxy"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
module Extensions
|
@@ -22,19 +23,20 @@ module Sidekiq
|
|
22
23
|
end
|
23
24
|
|
24
25
|
module ActiveRecord
|
25
|
-
def sidekiq_delay(options={})
|
26
|
+
def sidekiq_delay(options = {})
|
26
27
|
Proxy.new(DelayedModel, self, options)
|
27
28
|
end
|
28
|
-
|
29
|
-
|
29
|
+
|
30
|
+
def sidekiq_delay_for(interval, options = {})
|
31
|
+
Proxy.new(DelayedModel, self, options.merge("at" => Time.now.to_f + interval.to_f))
|
30
32
|
end
|
31
|
-
|
32
|
-
|
33
|
+
|
34
|
+
def sidekiq_delay_until(timestamp, options = {})
|
35
|
+
Proxy.new(DelayedModel, self, options.merge("at" => timestamp.to_f))
|
33
36
|
end
|
34
37
|
alias_method :delay, :sidekiq_delay
|
35
38
|
alias_method :delay_for, :sidekiq_delay_for
|
36
39
|
alias_method :delay_until, :sidekiq_delay_until
|
37
40
|
end
|
38
|
-
|
39
41
|
end
|
40
42
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "sidekiq/extensions/generic_proxy"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
module Extensions
|
@@ -20,20 +21,21 @@ module Sidekiq
|
|
20
21
|
end
|
21
22
|
|
22
23
|
module Klass
|
23
|
-
def sidekiq_delay(options={})
|
24
|
+
def sidekiq_delay(options = {})
|
24
25
|
Proxy.new(DelayedClass, self, options)
|
25
26
|
end
|
26
|
-
|
27
|
-
|
27
|
+
|
28
|
+
def sidekiq_delay_for(interval, options = {})
|
29
|
+
Proxy.new(DelayedClass, self, options.merge("at" => Time.now.to_f + interval.to_f))
|
28
30
|
end
|
29
|
-
|
30
|
-
|
31
|
+
|
32
|
+
def sidekiq_delay_until(timestamp, options = {})
|
33
|
+
Proxy.new(DelayedClass, self, options.merge("at" => timestamp.to_f))
|
31
34
|
end
|
32
35
|
alias_method :delay, :sidekiq_delay
|
33
36
|
alias_method :delay_for, :sidekiq_delay_for
|
34
37
|
alias_method :delay_until, :sidekiq_delay_until
|
35
38
|
end
|
36
|
-
|
37
39
|
end
|
38
40
|
end
|
39
41
|
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "yaml"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
module Extensions
|
6
7
|
SIZE_LIMIT = 8_192
|
7
8
|
|
8
9
|
class Proxy < BasicObject
|
9
|
-
def initialize(performable, target, options={})
|
10
|
+
def initialize(performable, target, options = {})
|
10
11
|
@performable = performable
|
11
12
|
@target = target
|
12
13
|
@opts = options
|
@@ -23,9 +24,8 @@ module Sidekiq
|
|
23
24
|
if marshalled.size > SIZE_LIMIT
|
24
25
|
::Sidekiq.logger.warn { "#{@target}.#{name} job argument is #{marshalled.bytesize} bytes, you should refactor it to reduce the size" }
|
25
26
|
end
|
26
|
-
@performable.client_push({
|
27
|
+
@performable.client_push({"class" => @performable, "args" => [marshalled]}.merge(@opts))
|
27
28
|
end
|
28
29
|
end
|
29
|
-
|
30
30
|
end
|
31
31
|
end
|
data/lib/sidekiq/fetch.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
|
3
|
+
require "sidekiq"
|
3
4
|
|
4
5
|
module Sidekiq
|
5
6
|
class BasicFetch
|
@@ -7,13 +8,13 @@ module Sidekiq
|
|
7
8
|
# can check if the process is shutting down.
|
8
9
|
TIMEOUT = 2
|
9
10
|
|
10
|
-
UnitOfWork = Struct.new(:queue, :job)
|
11
|
+
UnitOfWork = Struct.new(:queue, :job) {
|
11
12
|
def acknowledge
|
12
13
|
# nothing to do
|
13
14
|
end
|
14
15
|
|
15
16
|
def queue_name
|
16
|
-
queue.sub(/.*queue:/,
|
17
|
+
queue.sub(/.*queue:/, "")
|
17
18
|
end
|
18
19
|
|
19
20
|
def requeue
|
@@ -21,7 +22,7 @@ module Sidekiq
|
|
21
22
|
conn.rpush("queue:#{queue_name}", job)
|
22
23
|
end
|
23
24
|
end
|
24
|
-
|
25
|
+
}
|
25
26
|
|
26
27
|
def initialize(options)
|
27
28
|
@strictly_ordered_queues = !!options[:strict]
|
@@ -52,7 +53,6 @@ module Sidekiq
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
55
|
-
|
56
56
|
# By leaving this as a class method, it can be pluggable and used by the Manager actor. Making it
|
57
57
|
# an instance method will make it async to the Fetcher actor
|
58
58
|
def self.bulk_requeue(inprogress, options)
|
@@ -76,6 +76,5 @@ module Sidekiq
|
|
76
76
|
rescue => ex
|
77
77
|
Sidekiq.logger.warn("Failed to requeue #{inprogress.size} jobs: #{ex.message}")
|
78
78
|
end
|
79
|
-
|
80
79
|
end
|
81
80
|
end
|
data/lib/sidekiq/job_logger.rb
CHANGED
@@ -1,25 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Sidekiq
|
3
4
|
class JobLogger
|
5
|
+
def initialize(logger = Sidekiq.logger)
|
6
|
+
@logger = logger
|
7
|
+
end
|
4
8
|
|
5
9
|
def call(item, queue)
|
6
10
|
start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
7
|
-
logger.info("start")
|
11
|
+
@logger.info("start")
|
12
|
+
|
8
13
|
yield
|
9
|
-
|
14
|
+
|
15
|
+
with_elapsed_time_context(start) do
|
16
|
+
@logger.info("done")
|
17
|
+
end
|
10
18
|
rescue Exception
|
11
|
-
|
19
|
+
with_elapsed_time_context(start) do
|
20
|
+
@logger.info("fail")
|
21
|
+
end
|
22
|
+
|
12
23
|
raise
|
13
24
|
end
|
14
25
|
|
26
|
+
def with_job_hash_context(job_hash, &block)
|
27
|
+
@logger.with_context(job_hash_context(job_hash), &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def job_hash_context(job_hash)
|
31
|
+
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
32
|
+
# attribute to expose the underlying thing.
|
33
|
+
h = {
|
34
|
+
class: job_hash["wrapped"] || job_hash["class"],
|
35
|
+
jid: job_hash["jid"],
|
36
|
+
}
|
37
|
+
h[:bid] = job_hash["bid"] if job_hash["bid"]
|
38
|
+
h
|
39
|
+
end
|
40
|
+
|
41
|
+
def with_elapsed_time_context(start, &block)
|
42
|
+
@logger.with_context(elapsed_time_context(start), &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def elapsed_time_context(start)
|
46
|
+
{elapsed: elapsed(start).to_s}
|
47
|
+
end
|
48
|
+
|
15
49
|
private
|
16
50
|
|
17
51
|
def elapsed(start)
|
18
52
|
(::Process.clock_gettime(::Process::CLOCK_MONOTONIC) - start).round(3)
|
19
53
|
end
|
20
|
-
|
21
|
-
def logger
|
22
|
-
Sidekiq.logger
|
23
|
-
end
|
24
54
|
end
|
25
55
|
end
|