sidekiq 6.5.12 → 7.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changes.md +224 -20
- data/README.md +43 -35
- data/bin/multi_queue_bench +271 -0
- data/bin/sidekiq +3 -8
- data/bin/sidekiqload +204 -118
- data/bin/sidekiqmon +3 -0
- data/lib/sidekiq/api.rb +187 -135
- data/lib/sidekiq/capsule.rb +127 -0
- data/lib/sidekiq/cli.rb +59 -75
- data/lib/sidekiq/client.rb +66 -37
- data/lib/sidekiq/component.rb +4 -1
- data/lib/sidekiq/config.rb +287 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +11 -14
- data/lib/sidekiq/job.rb +371 -10
- data/lib/sidekiq/job_logger.rb +2 -2
- data/lib/sidekiq/job_retry.rb +36 -18
- data/lib/sidekiq/job_util.rb +51 -15
- data/lib/sidekiq/launcher.rb +71 -65
- data/lib/sidekiq/logger.rb +2 -27
- data/lib/sidekiq/manager.rb +9 -11
- data/lib/sidekiq/metrics/query.rb +7 -4
- data/lib/sidekiq/metrics/shared.rb +8 -7
- data/lib/sidekiq/metrics/tracking.rb +27 -21
- data/lib/sidekiq/middleware/chain.rb +19 -18
- data/lib/sidekiq/middleware/current_attributes.rb +52 -20
- data/lib/sidekiq/monitor.rb +16 -3
- data/lib/sidekiq/paginator.rb +2 -2
- data/lib/sidekiq/processor.rb +46 -51
- data/lib/sidekiq/rails.rb +15 -10
- data/lib/sidekiq/redis_client_adapter.rb +23 -66
- data/lib/sidekiq/redis_connection.rb +15 -117
- data/lib/sidekiq/scheduled.rb +22 -23
- data/lib/sidekiq/testing.rb +32 -41
- data/lib/sidekiq/transaction_aware_client.rb +11 -5
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +8 -3
- data/lib/sidekiq/web/application.rb +108 -15
- data/lib/sidekiq/web/csrf_protection.rb +10 -7
- data/lib/sidekiq/web/helpers.rb +52 -38
- data/lib/sidekiq/web.rb +17 -16
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +76 -274
- data/sidekiq.gemspec +12 -10
- data/web/assets/javascripts/application.js +39 -0
- data/web/assets/javascripts/base-charts.js +106 -0
- data/web/assets/javascripts/dashboard-charts.js +182 -0
- data/web/assets/javascripts/dashboard.js +10 -232
- data/web/assets/javascripts/metrics.js +151 -115
- data/web/assets/stylesheets/application-dark.css +4 -0
- data/web/assets/stylesheets/application-rtl.css +10 -89
- data/web/assets/stylesheets/application.css +45 -298
- data/web/locales/ar.yml +70 -70
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +60 -53
- data/web/locales/de.yml +65 -65
- data/web/locales/el.yml +2 -7
- data/web/locales/en.yml +78 -70
- data/web/locales/es.yml +68 -68
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +81 -67
- data/web/locales/gd.yml +99 -0
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +53 -53
- data/web/locales/ja.yml +67 -69
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +66 -66
- data/web/locales/nb.yml +61 -61
- data/web/locales/nl.yml +52 -52
- data/web/locales/pl.yml +45 -45
- data/web/locales/pt-br.yml +79 -69
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +67 -66
- data/web/locales/sv.yml +53 -53
- data/web/locales/ta.yml +60 -60
- data/web/locales/uk.yml +62 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +67 -67
- data/web/locales/zh-cn.yml +20 -18
- data/web/locales/zh-tw.yml +10 -1
- data/web/views/_footer.erb +17 -2
- data/web/views/_job_info.erb +18 -2
- data/web/views/_metrics_period_select.erb +12 -0
- data/web/views/_paging.erb +2 -0
- data/web/views/_poll_link.erb +1 -1
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +46 -35
- data/web/views/dashboard.erb +26 -5
- data/web/views/filtering.erb +7 -0
- data/web/views/metrics.erb +46 -24
- data/web/views/metrics_for_job.erb +41 -69
- data/web/views/morgue.erb +5 -9
- data/web/views/queue.erb +10 -14
- data/web/views/queues.erb +9 -3
- data/web/views/retries.erb +5 -9
- data/web/views/scheduled.erb +12 -13
- metadata +44 -38
- data/lib/sidekiq/delay.rb +0 -43
- data/lib/sidekiq/extensions/action_mailer.rb +0 -48
- data/lib/sidekiq/extensions/active_record.rb +0 -43
- data/lib/sidekiq/extensions/class_methods.rb +0 -43
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
- data/lib/sidekiq/metrics/deploy.rb +0 -47
- data/lib/sidekiq/worker.rb +0 -370
- data/web/assets/javascripts/graph.js +0 -16
- /data/{LICENSE → LICENSE.txt} +0 -0
@@ -27,7 +27,6 @@
|
|
27
27
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
28
28
|
|
29
29
|
require "securerandom"
|
30
|
-
require "base64"
|
31
30
|
require "rack/request"
|
32
31
|
|
33
32
|
module Sidekiq
|
@@ -57,12 +56,12 @@ module Sidekiq
|
|
57
56
|
end
|
58
57
|
|
59
58
|
def logger(env)
|
60
|
-
@logger ||=
|
59
|
+
@logger ||= env["rack.logger"] || ::Logger.new(env["rack.errors"])
|
61
60
|
end
|
62
61
|
|
63
62
|
def deny(env)
|
64
63
|
logger(env).warn "attack prevented by #{self.class}"
|
65
|
-
[403, {
|
64
|
+
[403, {Rack::CONTENT_TYPE => "text/plain"}, ["Forbidden"]]
|
66
65
|
end
|
67
66
|
|
68
67
|
def session(env)
|
@@ -116,7 +115,7 @@ module Sidekiq
|
|
116
115
|
sess = session(env)
|
117
116
|
localtoken = sess[:csrf]
|
118
117
|
|
119
|
-
# Checks that Rack::Session::Cookie
|
118
|
+
# Checks that Rack::Session::Cookie actually contains the csrf token
|
120
119
|
return false if localtoken.nil?
|
121
120
|
|
122
121
|
# Rotate the session token after every use
|
@@ -143,7 +142,7 @@ module Sidekiq
|
|
143
142
|
one_time_pad = SecureRandom.random_bytes(token.length)
|
144
143
|
encrypted_token = xor_byte_strings(one_time_pad, token)
|
145
144
|
masked_token = one_time_pad + encrypted_token
|
146
|
-
|
145
|
+
encode_token(masked_token)
|
147
146
|
end
|
148
147
|
|
149
148
|
# Essentially the inverse of +mask_token+.
|
@@ -152,7 +151,7 @@ module Sidekiq
|
|
152
151
|
# value and decrypt it
|
153
152
|
token_length = masked_token.length / 2
|
154
153
|
one_time_pad = masked_token[0...token_length]
|
155
|
-
encrypted_token = masked_token[token_length
|
154
|
+
encrypted_token = masked_token[token_length..]
|
156
155
|
xor_byte_strings(one_time_pad, encrypted_token)
|
157
156
|
end
|
158
157
|
|
@@ -168,8 +167,12 @@ module Sidekiq
|
|
168
167
|
::Rack::Utils.secure_compare(token.to_s, decode_token(local).to_s)
|
169
168
|
end
|
170
169
|
|
170
|
+
def encode_token(token)
|
171
|
+
[token].pack("m0").tr("+/", "-_")
|
172
|
+
end
|
173
|
+
|
171
174
|
def decode_token(token)
|
172
|
-
|
175
|
+
token.tr("-_", "+/").unpack1("m0")
|
173
176
|
end
|
174
177
|
|
175
178
|
def xor_byte_strings(s1, s2)
|
data/lib/sidekiq/web/helpers.rb
CHANGED
@@ -15,12 +15,16 @@ 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.safe_load(File.
|
18
|
+
strs = YAML.safe_load(File.read(file))
|
19
19
|
global.merge!(strs[lang])
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def to_json(x)
|
25
|
+
Sidekiq.dump_json(x)
|
26
|
+
end
|
27
|
+
|
24
28
|
def singularize(str, count)
|
25
29
|
if count == 1 && str.respond_to?(:singularize) # rails
|
26
30
|
str.singularize
|
@@ -49,8 +53,29 @@ module Sidekiq
|
|
49
53
|
locale_files.select { |file| file =~ /\/#{lang}\.yml$/ }
|
50
54
|
end
|
51
55
|
|
52
|
-
|
53
|
-
|
56
|
+
def search(jobset, substr)
|
57
|
+
resultset = jobset.scan(substr).to_a
|
58
|
+
@current_page = 1
|
59
|
+
@count = @total_size = resultset.size
|
60
|
+
resultset
|
61
|
+
end
|
62
|
+
|
63
|
+
def filtering(which)
|
64
|
+
erb(:filtering, locals: {which: which})
|
65
|
+
end
|
66
|
+
|
67
|
+
def filter_link(jid, within = "retries")
|
68
|
+
if within.nil?
|
69
|
+
::Rack::Utils.escape_html(jid)
|
70
|
+
else
|
71
|
+
"<a href='#{root_path}filter/#{within}?substr=#{jid}'>#{::Rack::Utils.escape_html(jid)}</a>"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def display_tags(job, within = "retries")
|
76
|
+
job.tags.map { |tag|
|
77
|
+
"<span class='label label-info jobtag'>#{filter_link(tag, within)}</span>"
|
78
|
+
}.join(" ")
|
54
79
|
end
|
55
80
|
|
56
81
|
# This view helper provide ability display you html code in
|
@@ -96,6 +121,10 @@ module Sidekiq
|
|
96
121
|
#
|
97
122
|
# Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
|
98
123
|
def locale
|
124
|
+
# session[:locale] is set via the locale selector from the footer
|
125
|
+
# defined?(session) && session are used to avoid exceptions when running tests
|
126
|
+
return session[:locale] if defined?(session) && session&.[](:locale)
|
127
|
+
|
99
128
|
@locale ||= begin
|
100
129
|
matched_locale = user_preferred_languages.map { |preferred|
|
101
130
|
preferred_language = preferred.split("-", 2).first
|
@@ -111,14 +140,7 @@ module Sidekiq
|
|
111
140
|
end
|
112
141
|
end
|
113
142
|
|
114
|
-
#
|
115
|
-
def display_tags(job, within = nil)
|
116
|
-
job.tags.map { |tag|
|
117
|
-
"<span class='label label-info jobtag'>#{::Rack::Utils.escape_html(tag)}</span>"
|
118
|
-
}.join(" ")
|
119
|
-
end
|
120
|
-
|
121
|
-
# mperham/sidekiq#3243
|
143
|
+
# sidekiq/sidekiq#3243
|
122
144
|
def unfiltered?
|
123
145
|
yield unless env["PATH_INFO"].start_with?("/filter/")
|
124
146
|
end
|
@@ -161,22 +183,26 @@ module Sidekiq
|
|
161
183
|
end
|
162
184
|
end
|
163
185
|
|
186
|
+
def busy_weights(capsule_weights)
|
187
|
+
# backwards compat with 7.0.0, remove in 7.1
|
188
|
+
cw = [capsule_weights].flatten
|
189
|
+
cw.map { |hash|
|
190
|
+
hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
|
191
|
+
}.join("; ")
|
192
|
+
end
|
193
|
+
|
164
194
|
def stats
|
165
195
|
@stats ||= Sidekiq::Stats.new
|
166
196
|
end
|
167
197
|
|
168
|
-
def
|
198
|
+
def redis_url
|
169
199
|
Sidekiq.redis do |conn|
|
170
|
-
conn.
|
200
|
+
conn.config.server_url
|
171
201
|
end
|
172
202
|
end
|
173
203
|
|
174
|
-
def namespace
|
175
|
-
@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
|
176
|
-
end
|
177
|
-
|
178
204
|
def redis_info
|
179
|
-
Sidekiq.redis_info
|
205
|
+
Sidekiq.default_configuration.redis_info
|
180
206
|
end
|
181
207
|
|
182
208
|
def root_path
|
@@ -274,23 +300,13 @@ module Sidekiq
|
|
274
300
|
elsif rss_kb < 10_000_000
|
275
301
|
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
276
302
|
else
|
277
|
-
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0))
|
303
|
+
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)), precision: 1)} GB"
|
278
304
|
end
|
279
305
|
end
|
280
306
|
|
281
|
-
def number_with_delimiter(number)
|
282
|
-
|
283
|
-
|
284
|
-
begin
|
285
|
-
Float(number)
|
286
|
-
rescue ArgumentError, TypeError
|
287
|
-
return number
|
288
|
-
end
|
289
|
-
|
290
|
-
options = {delimiter: ",", separator: "."}
|
291
|
-
parts = number.to_s.to_str.split(".")
|
292
|
-
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
|
293
|
-
parts.join(options[:separator])
|
307
|
+
def number_with_delimiter(number, options = {})
|
308
|
+
precision = options[:precision] || 0
|
309
|
+
%(<span data-nwp="#{precision}">#{number.round(precision)}</span>)
|
294
310
|
end
|
295
311
|
|
296
312
|
def h(text)
|
@@ -314,7 +330,7 @@ module Sidekiq
|
|
314
330
|
end
|
315
331
|
|
316
332
|
def environment_title_prefix
|
317
|
-
environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
333
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
318
334
|
|
319
335
|
"[#{environment.upcase}] " unless environment == "production"
|
320
336
|
end
|
@@ -327,11 +343,9 @@ module Sidekiq
|
|
327
343
|
Time.now.utc.strftime("%H:%M:%S UTC")
|
328
344
|
end
|
329
345
|
|
330
|
-
def
|
331
|
-
|
332
|
-
|
333
|
-
"#{redis_connection}#{namespace_suffix}"
|
334
|
-
end
|
346
|
+
def pollable?
|
347
|
+
# there's no point to refreshing the metrics pages every N seconds
|
348
|
+
!(current_path == "" || current_path.index("metrics"))
|
335
349
|
end
|
336
350
|
|
337
351
|
def retry_or_delete_or_kill(job, params)
|
data/lib/sidekiq/web.rb
CHANGED
@@ -30,11 +30,20 @@ module Sidekiq
|
|
30
30
|
"Queues" => "queues",
|
31
31
|
"Retries" => "retries",
|
32
32
|
"Scheduled" => "scheduled",
|
33
|
-
"Dead" => "morgue"
|
33
|
+
"Dead" => "morgue",
|
34
|
+
"Metrics" => "metrics"
|
34
35
|
}
|
35
36
|
|
36
|
-
if
|
37
|
-
|
37
|
+
if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
|
38
|
+
CONTENT_LANGUAGE = "Content-Language"
|
39
|
+
CONTENT_SECURITY_POLICY = "Content-Security-Policy"
|
40
|
+
LOCATION = "Location"
|
41
|
+
X_CASCADE = "X-Cascade"
|
42
|
+
else
|
43
|
+
CONTENT_LANGUAGE = "content-language"
|
44
|
+
CONTENT_SECURITY_POLICY = "content-security-policy"
|
45
|
+
LOCATION = "location"
|
46
|
+
X_CASCADE = "x-cascade"
|
38
47
|
end
|
39
48
|
|
40
49
|
class << self
|
@@ -51,6 +60,10 @@ module Sidekiq
|
|
51
60
|
end
|
52
61
|
alias_method :tabs, :custom_tabs
|
53
62
|
|
63
|
+
def custom_job_info_rows
|
64
|
+
@custom_job_info_rows ||= []
|
65
|
+
end
|
66
|
+
|
54
67
|
def locales
|
55
68
|
@locales ||= LOCALES
|
56
69
|
end
|
@@ -79,14 +92,6 @@ module Sidekiq
|
|
79
92
|
send(:"#{attribute}=", value)
|
80
93
|
end
|
81
94
|
|
82
|
-
def sessions=(val)
|
83
|
-
puts "WARNING: Sidekiq::Web.sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
|
84
|
-
end
|
85
|
-
|
86
|
-
def session_secret=(val)
|
87
|
-
puts "WARNING: Sidekiq::Web.session_secret= is no longer relevant and will be removed in Sidekiq 7.0. #{caller(1..1).first}"
|
88
|
-
end
|
89
|
-
|
90
95
|
attr_accessor :app_url, :redis_pool
|
91
96
|
attr_writer :locales, :views
|
92
97
|
end
|
@@ -133,10 +138,6 @@ module Sidekiq
|
|
133
138
|
send(:"#{attribute}=", value)
|
134
139
|
end
|
135
140
|
|
136
|
-
def sessions=(val)
|
137
|
-
puts "Sidekiq::Web#sessions= is no longer relevant and will be removed in Sidekiq 7.0. #{caller[2..2].first}"
|
138
|
-
end
|
139
|
-
|
140
141
|
def self.register(extension)
|
141
142
|
extension.registered(WebApplication)
|
142
143
|
end
|
@@ -148,7 +149,7 @@ module Sidekiq
|
|
148
149
|
m = middlewares
|
149
150
|
|
150
151
|
rules = []
|
151
|
-
rules = [[:all, {
|
152
|
+
rules = [[:all, {Rack::CACHE_CONTROL => "private, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
|
152
153
|
|
153
154
|
::Rack::Builder.new do
|
154
155
|
use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
# Sidekiq::Job is a new alias for Sidekiq::Worker as of Sidekiq 6.3.0.
|
5
|
+
# Use `include Sidekiq::Job` rather than `include Sidekiq::Worker`.
|
6
|
+
#
|
7
|
+
# The term "worker" is too generic and overly confusing, used in several
|
8
|
+
# different contexts meaning different things. Many people call a Sidekiq
|
9
|
+
# process a "worker". Some people call the thread that executes jobs a
|
10
|
+
# "worker". This change brings Sidekiq closer to ActiveJob where your job
|
11
|
+
# classes extend ApplicationJob.
|
12
|
+
Worker = Job
|
13
|
+
end
|