sidekiq 5.2.4 → 7.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changes.md +672 -8
- data/LICENSE.txt +9 -0
- data/README.md +48 -51
- data/bin/multi_queue_bench +271 -0
- data/bin/sidekiq +22 -3
- data/bin/sidekiqload +213 -115
- data/bin/sidekiqmon +11 -0
- data/lib/generators/sidekiq/job_generator.rb +57 -0
- data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
- data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
- data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
- data/lib/sidekiq/api.rb +623 -352
- data/lib/sidekiq/capsule.rb +127 -0
- data/lib/sidekiq/cli.rb +214 -229
- data/lib/sidekiq/client.rb +127 -102
- data/lib/sidekiq/component.rb +68 -0
- 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 +49 -42
- data/lib/sidekiq/job.rb +374 -0
- data/lib/sidekiq/job_logger.rb +33 -7
- data/lib/sidekiq/job_retry.rb +157 -108
- data/lib/sidekiq/job_util.rb +107 -0
- data/lib/sidekiq/launcher.rb +206 -106
- data/lib/sidekiq/logger.rb +131 -0
- data/lib/sidekiq/manager.rb +43 -46
- data/lib/sidekiq/metrics/query.rb +156 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +140 -0
- data/lib/sidekiq/middleware/chain.rb +113 -56
- data/lib/sidekiq/middleware/current_attributes.rb +95 -0
- data/lib/sidekiq/middleware/i18n.rb +7 -7
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +146 -0
- data/lib/sidekiq/paginator.rb +28 -16
- data/lib/sidekiq/processor.rb +126 -117
- data/lib/sidekiq/rails.rb +52 -38
- data/lib/sidekiq/redis_client_adapter.rb +111 -0
- data/lib/sidekiq/redis_connection.rb +41 -112
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +112 -50
- data/lib/sidekiq/sd_notify.rb +149 -0
- data/lib/sidekiq/systemd.rb +24 -0
- data/lib/sidekiq/testing/inline.rb +6 -5
- data/lib/sidekiq/testing.rb +91 -90
- data/lib/sidekiq/transaction_aware_client.rb +51 -0
- data/lib/sidekiq/version.rb +3 -1
- data/lib/sidekiq/web/action.rb +20 -11
- data/lib/sidekiq/web/application.rb +202 -80
- data/lib/sidekiq/web/csrf_protection.rb +183 -0
- data/lib/sidekiq/web/helpers.rb +165 -114
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +68 -107
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +92 -182
- data/sidekiq.gemspec +25 -16
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +152 -61
- data/web/assets/javascripts/base-charts.js +106 -0
- 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-charts.js +182 -0
- data/web/assets/javascripts/dashboard.js +35 -293
- data/web/assets/javascripts/metrics.js +298 -0
- data/web/assets/stylesheets/application-dark.css +147 -0
- data/web/assets/stylesheets/application-rtl.css +10 -93
- data/web/assets/stylesheets/application.css +124 -522
- data/web/assets/stylesheets/bootstrap.css +1 -1
- data/web/locales/ar.yml +71 -65
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +60 -53
- data/web/locales/de.yml +65 -53
- data/web/locales/el.yml +43 -24
- data/web/locales/en.yml +86 -66
- data/web/locales/es.yml +70 -54
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +83 -62
- 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 +75 -64
- data/web/locales/ko.yml +52 -52
- data/web/locales/lt.yml +83 -0
- 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 +83 -55
- data/web/locales/pt.yml +51 -51
- data/web/locales/ru.yml +68 -63
- 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 +83 -0
- data/web/locales/zh-cn.yml +43 -16
- data/web/locales/zh-tw.yml +42 -8
- data/web/views/_footer.erb +18 -3
- data/web/views/_job_info.erb +21 -4
- data/web/views/_metrics_period_select.erb +12 -0
- data/web/views/_nav.erb +1 -1
- data/web/views/_paging.erb +2 -0
- data/web/views/_poll_link.erb +3 -6
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +79 -29
- data/web/views/dashboard.erb +48 -18
- data/web/views/dead.erb +3 -3
- data/web/views/filtering.erb +7 -0
- data/web/views/layout.erb +3 -1
- data/web/views/metrics.erb +91 -0
- data/web/views/metrics_for_job.erb +59 -0
- data/web/views/morgue.erb +14 -15
- data/web/views/queue.erb +33 -24
- data/web/views/queues.erb +19 -5
- data/web/views/retries.erb +16 -17
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +17 -15
- metadata +71 -72
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -15
- data/.travis.yml +0 -17
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/Appraisals +0 -9
- data/COMM-LICENSE +0 -95
- data/Ent-Changes.md +0 -225
- data/Gemfile +0 -29
- data/LICENSE +0 -9
- data/Pro-2.0-Upgrade.md +0 -138
- data/Pro-3.0-Upgrade.md +0 -44
- data/Pro-4.0-Upgrade.md +0 -35
- data/Pro-Changes.md +0 -752
- data/Rakefile +0 -9
- data/bin/sidekiqctl +0 -237
- data/code_of_conduct.md +0 -50
- data/gemfiles/rails_4.gemfile +0 -31
- data/gemfiles/rails_5.gemfile +0 -31
- data/lib/generators/sidekiq/worker_generator.rb +0 -49
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/delay.rb +0 -42
- data/lib/sidekiq/exception_handler.rb +0 -29
- data/lib/sidekiq/extensions/action_mailer.rb +0 -57
- data/lib/sidekiq/extensions/active_record.rb +0 -40
- data/lib/sidekiq/extensions/class_methods.rb +0 -40
- data/lib/sidekiq/extensions/generic_proxy.rb +0 -31
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -23
- data/lib/sidekiq/util.rb +0 -66
- data/lib/sidekiq/worker.rb +0 -215
data/lib/sidekiq/web/helpers.rb
CHANGED
|
@@ -1,48 +1,81 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
2
|
+
|
|
3
|
+
require "uri"
|
|
4
|
+
require "set"
|
|
5
|
+
require "yaml"
|
|
6
|
+
require "cgi"
|
|
6
7
|
|
|
7
8
|
module Sidekiq
|
|
8
9
|
# This is not a public API
|
|
9
10
|
module WebHelpers
|
|
10
11
|
def strings(lang)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
12
|
+
@strings ||= {}
|
|
13
|
+
|
|
14
|
+
# Allow sidekiq-web extensions to add locale paths
|
|
15
|
+
# so extensions can be localized
|
|
16
|
+
@strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
|
|
17
|
+
find_locale_files(lang).each do |file|
|
|
18
|
+
strs = YAML.safe_load(File.read(file))
|
|
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
|
+
|
|
28
|
+
def singularize(str, count)
|
|
29
|
+
if count == 1 && str.respond_to?(:singularize) # rails
|
|
30
|
+
str.singularize
|
|
31
|
+
else
|
|
32
|
+
str
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
24
36
|
def clear_caches
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
37
|
+
@strings = nil
|
|
38
|
+
@locale_files = nil
|
|
39
|
+
@available_locales = nil
|
|
28
40
|
end
|
|
29
41
|
|
|
30
42
|
def locale_files
|
|
31
|
-
|
|
43
|
+
@locale_files ||= settings.locales.flat_map { |path|
|
|
32
44
|
Dir["#{path}/*.yml"]
|
|
33
|
-
|
|
45
|
+
}
|
|
34
46
|
end
|
|
35
47
|
|
|
36
48
|
def available_locales
|
|
37
|
-
|
|
49
|
+
@available_locales ||= locale_files.map { |path| File.basename(path, ".yml") }.uniq
|
|
38
50
|
end
|
|
39
51
|
|
|
40
52
|
def find_locale_files(lang)
|
|
41
53
|
locale_files.select { |file| file =~ /\/#{lang}\.yml$/ }
|
|
42
54
|
end
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
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(" ")
|
|
46
79
|
end
|
|
47
80
|
|
|
48
81
|
# This view helper provide ability display you html code in
|
|
@@ -62,33 +95,25 @@ module Sidekiq
|
|
|
62
95
|
@head_html.join if defined?(@head_html)
|
|
63
96
|
end
|
|
64
97
|
|
|
65
|
-
def poll_path
|
|
66
|
-
if current_path != '' && params['poll']
|
|
67
|
-
root_path + current_path
|
|
68
|
-
else
|
|
69
|
-
""
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
98
|
def text_direction
|
|
74
|
-
get_locale[
|
|
99
|
+
get_locale["TextDirection"] || "ltr"
|
|
75
100
|
end
|
|
76
101
|
|
|
77
102
|
def rtl?
|
|
78
|
-
text_direction ==
|
|
103
|
+
text_direction == "rtl"
|
|
79
104
|
end
|
|
80
105
|
|
|
81
106
|
# See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
|
|
82
107
|
def user_preferred_languages
|
|
83
|
-
languages = env[
|
|
84
|
-
languages.to_s.downcase.gsub(/\s+/,
|
|
85
|
-
locale, quality = language.split(
|
|
86
|
-
locale
|
|
108
|
+
languages = env["HTTP_ACCEPT_LANGUAGE"]
|
|
109
|
+
languages.to_s.downcase.gsub(/\s+/, "").split(",").map { |language|
|
|
110
|
+
locale, quality = language.split(";q=", 2)
|
|
111
|
+
locale = nil if locale == "*" # Ignore wildcards
|
|
87
112
|
quality = quality ? quality.to_f : 1.0
|
|
88
113
|
[locale, quality]
|
|
89
|
-
|
|
114
|
+
}.sort { |(_, left), (_, right)|
|
|
90
115
|
right <=> left
|
|
91
|
-
|
|
116
|
+
}.map(&:first).compact
|
|
92
117
|
end
|
|
93
118
|
|
|
94
119
|
# Given an Accept-Language header like "fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,ru;q=0.2"
|
|
@@ -96,32 +121,36 @@ 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
|
-
matched_locale = user_preferred_languages.map
|
|
101
|
-
preferred_language = preferred.split(
|
|
129
|
+
matched_locale = user_preferred_languages.map { |preferred|
|
|
130
|
+
preferred_language = preferred.split("-", 2).first
|
|
102
131
|
|
|
103
|
-
lang_group = available_locales.select
|
|
104
|
-
preferred_language == available.split(
|
|
105
|
-
|
|
132
|
+
lang_group = available_locales.select { |available|
|
|
133
|
+
preferred_language == available.split("-", 2).first
|
|
134
|
+
}
|
|
106
135
|
|
|
107
136
|
lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
|
|
108
|
-
|
|
137
|
+
}.compact.first
|
|
109
138
|
|
|
110
|
-
matched_locale ||
|
|
139
|
+
matched_locale || "en"
|
|
111
140
|
end
|
|
112
141
|
end
|
|
113
142
|
|
|
114
|
-
#
|
|
143
|
+
# sidekiq/sidekiq#3243
|
|
115
144
|
def unfiltered?
|
|
116
|
-
yield unless env[
|
|
145
|
+
yield unless env["PATH_INFO"].start_with?("/filter/")
|
|
117
146
|
end
|
|
118
147
|
|
|
119
148
|
def get_locale
|
|
120
149
|
strings(locale)
|
|
121
150
|
end
|
|
122
151
|
|
|
123
|
-
def t(msg, options={})
|
|
124
|
-
string = get_locale[msg] || strings(
|
|
152
|
+
def t(msg, options = {})
|
|
153
|
+
string = get_locale[msg] || strings("en")[msg] || msg
|
|
125
154
|
if options.empty?
|
|
126
155
|
string
|
|
127
156
|
else
|
|
@@ -129,58 +158,72 @@ module Sidekiq
|
|
|
129
158
|
end
|
|
130
159
|
end
|
|
131
160
|
|
|
132
|
-
def
|
|
133
|
-
|
|
161
|
+
def sort_direction_label
|
|
162
|
+
(params[:direction] == "asc") ? "↑" : "↓"
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def workset
|
|
166
|
+
@work ||= Sidekiq::WorkSet.new
|
|
134
167
|
end
|
|
135
168
|
|
|
136
169
|
def processes
|
|
137
170
|
@processes ||= Sidekiq::ProcessSet.new
|
|
138
171
|
end
|
|
139
172
|
|
|
140
|
-
|
|
141
|
-
|
|
173
|
+
# Sorts processes by hostname following the natural sort order
|
|
174
|
+
def sorted_processes
|
|
175
|
+
@sorted_processes ||= begin
|
|
176
|
+
return processes unless processes.all? { |p| p["hostname"] }
|
|
177
|
+
|
|
178
|
+
processes.to_a.sort_by do |process|
|
|
179
|
+
# Kudos to `shurikk` on StackOverflow
|
|
180
|
+
# https://stackoverflow.com/a/15170063/575547
|
|
181
|
+
process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
|
|
182
|
+
end
|
|
183
|
+
end
|
|
142
184
|
end
|
|
143
185
|
|
|
144
|
-
def
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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("; ")
|
|
148
192
|
end
|
|
149
193
|
|
|
150
|
-
def
|
|
151
|
-
Sidekiq.
|
|
152
|
-
c = conn.connection
|
|
153
|
-
"redis://#{c[:location]}/#{c[:db]}"
|
|
154
|
-
end
|
|
194
|
+
def stats
|
|
195
|
+
@stats ||= Sidekiq::Stats.new
|
|
155
196
|
end
|
|
156
197
|
|
|
157
|
-
def
|
|
158
|
-
|
|
198
|
+
def redis_url
|
|
199
|
+
Sidekiq.redis do |conn|
|
|
200
|
+
conn.config.server_url
|
|
201
|
+
end
|
|
159
202
|
end
|
|
160
203
|
|
|
161
204
|
def redis_info
|
|
162
|
-
Sidekiq.redis_info
|
|
205
|
+
Sidekiq.default_configuration.redis_info
|
|
163
206
|
end
|
|
164
207
|
|
|
165
208
|
def root_path
|
|
166
|
-
"#{env[
|
|
209
|
+
"#{env["SCRIPT_NAME"]}/"
|
|
167
210
|
end
|
|
168
211
|
|
|
169
212
|
def current_path
|
|
170
|
-
@current_path ||= request.path_info.gsub(/^\//,
|
|
213
|
+
@current_path ||= request.path_info.gsub(/^\//, "")
|
|
171
214
|
end
|
|
172
215
|
|
|
173
216
|
def current_status
|
|
174
|
-
|
|
217
|
+
(workset.size == 0) ? "idle" : "active"
|
|
175
218
|
end
|
|
176
219
|
|
|
177
220
|
def relative_time(time)
|
|
178
221
|
stamp = time.getutc.iso8601
|
|
179
|
-
%
|
|
222
|
+
%(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
|
|
180
223
|
end
|
|
181
224
|
|
|
182
225
|
def job_params(job, score)
|
|
183
|
-
"#{score}-#{job[
|
|
226
|
+
"#{score}-#{job["jid"]}"
|
|
184
227
|
end
|
|
185
228
|
|
|
186
229
|
def parse_params(params)
|
|
@@ -188,52 +231,58 @@ module Sidekiq
|
|
|
188
231
|
[score.to_f, jid]
|
|
189
232
|
end
|
|
190
233
|
|
|
191
|
-
SAFE_QPARAMS = %w
|
|
234
|
+
SAFE_QPARAMS = %w[page direction]
|
|
192
235
|
|
|
193
236
|
# Merge options with current params, filter safe params, and stringify to query string
|
|
194
237
|
def qparams(options)
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
238
|
+
stringified_options = options.transform_keys(&:to_s)
|
|
239
|
+
|
|
240
|
+
to_query_string(params.merge(stringified_options))
|
|
241
|
+
end
|
|
199
242
|
|
|
200
|
-
|
|
243
|
+
def to_query_string(params)
|
|
244
|
+
params.map { |key, value|
|
|
201
245
|
SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
|
|
202
|
-
|
|
246
|
+
}.compact.join("&")
|
|
203
247
|
end
|
|
204
248
|
|
|
205
249
|
def truncate(text, truncate_after_chars = 2000)
|
|
206
|
-
truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
|
|
250
|
+
(truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
|
|
207
251
|
end
|
|
208
252
|
|
|
209
253
|
def display_args(args, truncate_after_chars = 2000)
|
|
210
|
-
args
|
|
211
|
-
|
|
212
|
-
|
|
254
|
+
return "Invalid job payload, args is nil" if args.nil?
|
|
255
|
+
return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
|
|
256
|
+
|
|
257
|
+
begin
|
|
258
|
+
args.map { |arg|
|
|
259
|
+
h(truncate(to_display(arg), truncate_after_chars))
|
|
260
|
+
}.join(", ")
|
|
261
|
+
rescue
|
|
262
|
+
"Illegal job arguments: #{h args.inspect}"
|
|
263
|
+
end
|
|
213
264
|
end
|
|
214
265
|
|
|
215
266
|
def csrf_tag
|
|
216
|
-
"<input type='hidden' name='authenticity_token' value='#{
|
|
267
|
+
"<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
|
|
217
268
|
end
|
|
218
269
|
|
|
219
270
|
def to_display(arg)
|
|
271
|
+
arg.inspect
|
|
272
|
+
rescue
|
|
220
273
|
begin
|
|
221
|
-
arg.
|
|
222
|
-
rescue
|
|
223
|
-
|
|
224
|
-
arg.to_s
|
|
225
|
-
rescue => ex
|
|
226
|
-
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
|
227
|
-
end
|
|
274
|
+
arg.to_s
|
|
275
|
+
rescue => ex
|
|
276
|
+
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
|
228
277
|
end
|
|
229
278
|
end
|
|
230
279
|
|
|
231
|
-
RETRY_JOB_KEYS = Set.new(%w
|
|
280
|
+
RETRY_JOB_KEYS = Set.new(%w[
|
|
232
281
|
queue class args retry_count retried_at failed_at
|
|
233
282
|
jid error_message error_class backtrace
|
|
234
283
|
error_backtrace enqueued_at retry wrapped
|
|
235
|
-
created_at
|
|
236
|
-
)
|
|
284
|
+
created_at tags display_class
|
|
285
|
+
])
|
|
237
286
|
|
|
238
287
|
def retry_extra_items(retry_job)
|
|
239
288
|
@retry_extra_items ||= {}.tap do |extra|
|
|
@@ -243,24 +292,28 @@ module Sidekiq
|
|
|
243
292
|
end
|
|
244
293
|
end
|
|
245
294
|
|
|
246
|
-
def
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
295
|
+
def format_memory(rss_kb)
|
|
296
|
+
return "0" if rss_kb.nil? || rss_kb == 0
|
|
297
|
+
|
|
298
|
+
if rss_kb < 100_000
|
|
299
|
+
"#{number_with_delimiter(rss_kb)} KB"
|
|
300
|
+
elsif rss_kb < 10_000_000
|
|
301
|
+
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
|
302
|
+
else
|
|
303
|
+
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)), precision: 1)} GB"
|
|
251
304
|
end
|
|
305
|
+
end
|
|
252
306
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
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>)
|
|
257
310
|
end
|
|
258
311
|
|
|
259
312
|
def h(text)
|
|
260
313
|
::Rack::Utils.escape_html(text)
|
|
261
314
|
rescue ArgumentError => e
|
|
262
|
-
raise unless e.message.eql?(
|
|
263
|
-
text.encode!(
|
|
315
|
+
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
|
316
|
+
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
|
264
317
|
retry
|
|
265
318
|
end
|
|
266
319
|
|
|
@@ -277,7 +330,7 @@ module Sidekiq
|
|
|
277
330
|
end
|
|
278
331
|
|
|
279
332
|
def environment_title_prefix
|
|
280
|
-
environment = Sidekiq.
|
|
333
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
|
281
334
|
|
|
282
335
|
"[#{environment.upcase}] " unless environment == "production"
|
|
283
336
|
end
|
|
@@ -287,30 +340,28 @@ module Sidekiq
|
|
|
287
340
|
end
|
|
288
341
|
|
|
289
342
|
def server_utc_time
|
|
290
|
-
Time.now.utc.strftime(
|
|
343
|
+
Time.now.utc.strftime("%H:%M:%S UTC")
|
|
291
344
|
end
|
|
292
345
|
|
|
293
|
-
def
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
"#{redis_connection}#{namespace_suffix}"
|
|
297
|
-
end
|
|
346
|
+
def pollable?
|
|
347
|
+
# there's no point to refreshing the metrics pages every N seconds
|
|
348
|
+
!(current_path == "" || current_path.index("metrics"))
|
|
298
349
|
end
|
|
299
350
|
|
|
300
351
|
def retry_or_delete_or_kill(job, params)
|
|
301
|
-
if params[
|
|
352
|
+
if params["retry"]
|
|
302
353
|
job.retry
|
|
303
|
-
elsif params[
|
|
354
|
+
elsif params["delete"]
|
|
304
355
|
job.delete
|
|
305
|
-
elsif params[
|
|
356
|
+
elsif params["kill"]
|
|
306
357
|
job.kill
|
|
307
358
|
end
|
|
308
359
|
end
|
|
309
360
|
|
|
310
361
|
def delete_or_add_queue(job, params)
|
|
311
|
-
if params[
|
|
362
|
+
if params["delete"]
|
|
312
363
|
job.delete
|
|
313
|
-
elsif params[
|
|
364
|
+
elsif params["add_to_queue"]
|
|
314
365
|
job.add_to_queue
|
|
315
366
|
end
|
|
316
367
|
end
|
data/lib/sidekiq/web/router.rb
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
require "rack"
|
|
3
4
|
|
|
4
5
|
module Sidekiq
|
|
5
6
|
module WebRouter
|
|
6
|
-
GET =
|
|
7
|
-
DELETE =
|
|
8
|
-
POST =
|
|
9
|
-
PUT =
|
|
10
|
-
PATCH =
|
|
11
|
-
HEAD =
|
|
12
|
-
|
|
13
|
-
ROUTE_PARAMS =
|
|
14
|
-
REQUEST_METHOD =
|
|
15
|
-
PATH_INFO =
|
|
7
|
+
GET = "GET"
|
|
8
|
+
DELETE = "DELETE"
|
|
9
|
+
POST = "POST"
|
|
10
|
+
PUT = "PUT"
|
|
11
|
+
PATCH = "PATCH"
|
|
12
|
+
HEAD = "HEAD"
|
|
13
|
+
|
|
14
|
+
ROUTE_PARAMS = "rack.route_params"
|
|
15
|
+
REQUEST_METHOD = "REQUEST_METHOD"
|
|
16
|
+
PATH_INFO = "PATH_INFO"
|
|
17
|
+
|
|
18
|
+
def head(path, &block)
|
|
19
|
+
route(HEAD, path, &block)
|
|
20
|
+
end
|
|
16
21
|
|
|
17
22
|
def get(path, &block)
|
|
18
23
|
route(GET, path, &block)
|
|
@@ -35,10 +40,9 @@ module Sidekiq
|
|
|
35
40
|
end
|
|
36
41
|
|
|
37
42
|
def route(method, path, &block)
|
|
38
|
-
@routes ||= {
|
|
43
|
+
@routes ||= {GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => []}
|
|
39
44
|
|
|
40
45
|
@routes[method] << WebRoute.new(method, path, block)
|
|
41
|
-
@routes[HEAD] << WebRoute.new(method, path, block) if method == GET
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
def match(env)
|
|
@@ -50,7 +54,8 @@ module Sidekiq
|
|
|
50
54
|
path_info = "/" if path_info == ""
|
|
51
55
|
|
|
52
56
|
@routes[request_method].each do |route|
|
|
53
|
-
|
|
57
|
+
params = route.match(request_method, path_info)
|
|
58
|
+
if params
|
|
54
59
|
env[ROUTE_PARAMS] = params
|
|
55
60
|
|
|
56
61
|
return WebAction.new(env, route.block)
|
|
@@ -64,7 +69,7 @@ module Sidekiq
|
|
|
64
69
|
class WebRoute
|
|
65
70
|
attr_accessor :request_method, :pattern, :block, :name
|
|
66
71
|
|
|
67
|
-
NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([
|
|
72
|
+
NAMED_SEGMENTS_PATTERN = /\/([^\/]*):([^.:$\/]+)/
|
|
68
73
|
|
|
69
74
|
def initialize(request_method, pattern, block)
|
|
70
75
|
@request_method = request_method
|
|
@@ -77,7 +82,7 @@ module Sidekiq
|
|
|
77
82
|
end
|
|
78
83
|
|
|
79
84
|
def compile
|
|
80
|
-
if pattern.match(NAMED_SEGMENTS_PATTERN)
|
|
85
|
+
if pattern.match?(NAMED_SEGMENTS_PATTERN)
|
|
81
86
|
p = pattern.gsub(NAMED_SEGMENTS_PATTERN, '/\1(?<\2>[^$/]+)')
|
|
82
87
|
|
|
83
88
|
Regexp.new("\\A#{p}\\Z")
|
|
@@ -91,9 +96,8 @@ module Sidekiq
|
|
|
91
96
|
when String
|
|
92
97
|
{} if path == matcher
|
|
93
98
|
else
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
end
|
|
99
|
+
path_match = path.match(matcher)
|
|
100
|
+
path_match&.named_captures&.transform_keys(&:to_sym)
|
|
97
101
|
end
|
|
98
102
|
end
|
|
99
103
|
end
|