sidekiq 5.2.7 → 7.0.2
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 +465 -5
- data/LICENSE.txt +9 -0
- data/README.md +32 -42
- data/bin/sidekiq +22 -3
- data/bin/sidekiqload +80 -77
- data/bin/sidekiqmon +8 -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 +506 -351
- data/lib/sidekiq/capsule.rb +110 -0
- data/lib/sidekiq/cli.rb +202 -226
- data/lib/sidekiq/client.rb +104 -95
- data/lib/sidekiq/component.rb +66 -0
- data/lib/sidekiq/config.rb +270 -0
- data/lib/sidekiq/deploy.rb +62 -0
- data/lib/sidekiq/embedded.rb +61 -0
- data/lib/sidekiq/fetch.rb +49 -40
- data/lib/sidekiq/job.rb +378 -0
- data/lib/sidekiq/job_logger.rb +33 -7
- data/lib/sidekiq/job_retry.rb +127 -107
- data/lib/sidekiq/job_util.rb +71 -0
- data/lib/sidekiq/launcher.rb +197 -103
- data/lib/sidekiq/logger.rb +131 -0
- data/lib/sidekiq/manager.rb +43 -46
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +134 -0
- data/lib/sidekiq/middleware/chain.rb +104 -50
- data/lib/sidekiq/middleware/current_attributes.rb +58 -0
- data/lib/sidekiq/middleware/i18n.rb +7 -7
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +148 -0
- data/lib/sidekiq/paginator.rb +28 -16
- data/lib/sidekiq/processor.rb +105 -107
- data/lib/sidekiq/rails.rb +41 -37
- data/lib/sidekiq/redis_client_adapter.rb +115 -0
- data/lib/sidekiq/redis_connection.rb +38 -107
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +111 -49
- 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 +66 -84
- data/lib/sidekiq/transaction_aware_client.rb +44 -0
- data/lib/sidekiq/version.rb +3 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +108 -79
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +128 -105
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +56 -107
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +92 -182
- data/sidekiq.gemspec +45 -16
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +130 -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 +166 -0
- data/web/assets/javascripts/dashboard.js +36 -292
- data/web/assets/javascripts/metrics.js +236 -0
- data/web/assets/stylesheets/application-dark.css +147 -0
- data/web/assets/stylesheets/application-rtl.css +2 -95
- data/web/assets/stylesheets/application.css +102 -522
- data/web/locales/ar.yml +71 -65
- data/web/locales/cs.yml +62 -62
- data/web/locales/da.yml +52 -52
- data/web/locales/de.yml +65 -53
- data/web/locales/el.yml +43 -24
- data/web/locales/en.yml +84 -66
- data/web/locales/es.yml +70 -54
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +69 -62
- 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 +73 -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 +63 -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 +6 -3
- data/web/views/_job_info.erb +19 -2
- data/web/views/_nav.erb +1 -1
- data/web/views/_poll_link.erb +3 -6
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +74 -22
- data/web/views/dashboard.erb +58 -18
- data/web/views/dead.erb +3 -3
- data/web/views/layout.erb +3 -1
- data/web/views/metrics.erb +80 -0
- data/web/views/metrics_for_job.erb +69 -0
- data/web/views/morgue.erb +10 -7
- data/web/views/queue.erb +23 -10
- data/web/views/queues.erb +10 -2
- data/web/views/retries.erb +12 -9
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +6 -3
- metadata +84 -69
- data/.circleci/config.yml +0 -61
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -15
- data/.travis.yml +0 -11
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/COMM-LICENSE +0 -97
- data/Ent-Changes.md +0 -238
- data/Gemfile +0 -23
- 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 -759
- data/Rakefile +0 -9
- data/bin/sidekiqctl +0 -20
- data/code_of_conduct.md +0 -50
- data/lib/generators/sidekiq/worker_generator.rb +0 -49
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/ctl.rb +0 -221
- 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 -220
data/lib/sidekiq/web/helpers.rb
CHANGED
@@ -1,40 +1,48 @@
|
|
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.open(file))
|
19
|
+
global.merge!(strs[lang])
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
+
def singularize(str, count)
|
25
|
+
if count == 1 && str.respond_to?(:singularize) # rails
|
26
|
+
str.singularize
|
27
|
+
else
|
28
|
+
str
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
24
32
|
def clear_caches
|
25
|
-
|
26
|
-
|
27
|
-
|
33
|
+
@strings = nil
|
34
|
+
@locale_files = nil
|
35
|
+
@available_locales = nil
|
28
36
|
end
|
29
37
|
|
30
38
|
def locale_files
|
31
|
-
|
39
|
+
@locale_files ||= settings.locales.flat_map { |path|
|
32
40
|
Dir["#{path}/*.yml"]
|
33
|
-
|
41
|
+
}
|
34
42
|
end
|
35
43
|
|
36
44
|
def available_locales
|
37
|
-
|
45
|
+
@available_locales ||= locale_files.map { |path| File.basename(path, ".yml") }.uniq
|
38
46
|
end
|
39
47
|
|
40
48
|
def find_locale_files(lang)
|
@@ -62,33 +70,25 @@ module Sidekiq
|
|
62
70
|
@head_html.join if defined?(@head_html)
|
63
71
|
end
|
64
72
|
|
65
|
-
def poll_path
|
66
|
-
if current_path != '' && params['poll']
|
67
|
-
root_path + current_path
|
68
|
-
else
|
69
|
-
""
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
73
|
def text_direction
|
74
|
-
get_locale[
|
74
|
+
get_locale["TextDirection"] || "ltr"
|
75
75
|
end
|
76
76
|
|
77
77
|
def rtl?
|
78
|
-
text_direction ==
|
78
|
+
text_direction == "rtl"
|
79
79
|
end
|
80
80
|
|
81
81
|
# See https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
|
82
82
|
def user_preferred_languages
|
83
|
-
languages = env[
|
84
|
-
languages.to_s.downcase.gsub(/\s+/,
|
85
|
-
locale, quality = language.split(
|
86
|
-
locale
|
83
|
+
languages = env["HTTP_ACCEPT_LANGUAGE"]
|
84
|
+
languages.to_s.downcase.gsub(/\s+/, "").split(",").map { |language|
|
85
|
+
locale, quality = language.split(";q=", 2)
|
86
|
+
locale = nil if locale == "*" # Ignore wildcards
|
87
87
|
quality = quality ? quality.to_f : 1.0
|
88
88
|
[locale, quality]
|
89
|
-
|
89
|
+
}.sort { |(_, left), (_, right)|
|
90
90
|
right <=> left
|
91
|
-
|
91
|
+
}.map(&:first).compact
|
92
92
|
end
|
93
93
|
|
94
94
|
# 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"
|
@@ -97,31 +97,38 @@ module Sidekiq
|
|
97
97
|
# Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
|
98
98
|
def locale
|
99
99
|
@locale ||= begin
|
100
|
-
matched_locale = user_preferred_languages.map
|
101
|
-
preferred_language = preferred.split(
|
100
|
+
matched_locale = user_preferred_languages.map { |preferred|
|
101
|
+
preferred_language = preferred.split("-", 2).first
|
102
102
|
|
103
|
-
lang_group = available_locales.select
|
104
|
-
preferred_language == available.split(
|
105
|
-
|
103
|
+
lang_group = available_locales.select { |available|
|
104
|
+
preferred_language == available.split("-", 2).first
|
105
|
+
}
|
106
106
|
|
107
107
|
lang_group.find { |lang| lang == preferred } || lang_group.min_by(&:length)
|
108
|
-
|
108
|
+
}.compact.first
|
109
109
|
|
110
|
-
matched_locale ||
|
110
|
+
matched_locale || "en"
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
# within is used by Sidekiq Pro
|
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
|
+
|
114
121
|
# mperham/sidekiq#3243
|
115
122
|
def unfiltered?
|
116
|
-
yield unless env[
|
123
|
+
yield unless env["PATH_INFO"].start_with?("/filter/")
|
117
124
|
end
|
118
125
|
|
119
126
|
def get_locale
|
120
127
|
strings(locale)
|
121
128
|
end
|
122
129
|
|
123
|
-
def t(msg, options={})
|
124
|
-
string = get_locale[msg] || strings(
|
130
|
+
def t(msg, options = {})
|
131
|
+
string = get_locale[msg] || strings("en")[msg] || msg
|
125
132
|
if options.empty?
|
126
133
|
string
|
127
134
|
else
|
@@ -129,58 +136,64 @@ module Sidekiq
|
|
129
136
|
end
|
130
137
|
end
|
131
138
|
|
132
|
-
def
|
133
|
-
|
139
|
+
def sort_direction_label
|
140
|
+
(params[:direction] == "asc") ? "↑" : "↓"
|
141
|
+
end
|
142
|
+
|
143
|
+
def workset
|
144
|
+
@work ||= Sidekiq::WorkSet.new
|
134
145
|
end
|
135
146
|
|
136
147
|
def processes
|
137
148
|
@processes ||= Sidekiq::ProcessSet.new
|
138
149
|
end
|
139
150
|
|
140
|
-
|
141
|
-
|
151
|
+
# Sorts processes by hostname following the natural sort order
|
152
|
+
def sorted_processes
|
153
|
+
@sorted_processes ||= begin
|
154
|
+
return processes unless processes.all? { |p| p["hostname"] }
|
155
|
+
|
156
|
+
processes.to_a.sort_by do |process|
|
157
|
+
# Kudos to `shurikk` on StackOverflow
|
158
|
+
# https://stackoverflow.com/a/15170063/575547
|
159
|
+
process["hostname"].split(/(\d+)/).map { |a| /\d+/.match?(a) ? a.to_i : a }
|
160
|
+
end
|
161
|
+
end
|
142
162
|
end
|
143
163
|
|
144
|
-
def
|
145
|
-
Sidekiq.
|
146
|
-
conn.zrangebyscore('retry', score, score)
|
147
|
-
end.map { |msg| Sidekiq.load_json(msg) }
|
164
|
+
def stats
|
165
|
+
@stats ||= Sidekiq::Stats.new
|
148
166
|
end
|
149
167
|
|
150
|
-
def
|
168
|
+
def redis_url
|
151
169
|
Sidekiq.redis do |conn|
|
152
|
-
|
153
|
-
"redis://#{c[:location]}/#{c[:db]}"
|
170
|
+
conn.config.server_url
|
154
171
|
end
|
155
172
|
end
|
156
173
|
|
157
|
-
def namespace
|
158
|
-
@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
|
159
|
-
end
|
160
|
-
|
161
174
|
def redis_info
|
162
|
-
Sidekiq.redis_info
|
175
|
+
Sidekiq.default_configuration.redis_info
|
163
176
|
end
|
164
177
|
|
165
178
|
def root_path
|
166
|
-
"#{env[
|
179
|
+
"#{env["SCRIPT_NAME"]}/"
|
167
180
|
end
|
168
181
|
|
169
182
|
def current_path
|
170
|
-
@current_path ||= request.path_info.gsub(/^\//,
|
183
|
+
@current_path ||= request.path_info.gsub(/^\//, "")
|
171
184
|
end
|
172
185
|
|
173
186
|
def current_status
|
174
|
-
|
187
|
+
(workset.size == 0) ? "idle" : "active"
|
175
188
|
end
|
176
189
|
|
177
190
|
def relative_time(time)
|
178
191
|
stamp = time.getutc.iso8601
|
179
|
-
%
|
192
|
+
%(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
|
180
193
|
end
|
181
194
|
|
182
195
|
def job_params(job, score)
|
183
|
-
"#{score}-#{job[
|
196
|
+
"#{score}-#{job["jid"]}"
|
184
197
|
end
|
185
198
|
|
186
199
|
def parse_params(params)
|
@@ -188,59 +201,58 @@ module Sidekiq
|
|
188
201
|
[score.to_f, jid]
|
189
202
|
end
|
190
203
|
|
191
|
-
SAFE_QPARAMS = %w
|
204
|
+
SAFE_QPARAMS = %w[page direction]
|
192
205
|
|
193
206
|
# Merge options with current params, filter safe params, and stringify to query string
|
194
207
|
def qparams(options)
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
208
|
+
stringified_options = options.transform_keys(&:to_s)
|
209
|
+
|
210
|
+
to_query_string(params.merge(stringified_options))
|
211
|
+
end
|
199
212
|
|
200
|
-
|
213
|
+
def to_query_string(params)
|
214
|
+
params.map { |key, value|
|
201
215
|
SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
|
202
|
-
|
216
|
+
}.compact.join("&")
|
203
217
|
end
|
204
218
|
|
205
219
|
def truncate(text, truncate_after_chars = 2000)
|
206
|
-
truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
|
220
|
+
(truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
|
207
221
|
end
|
208
222
|
|
209
223
|
def display_args(args, truncate_after_chars = 2000)
|
210
|
-
return "Invalid job payload, args is nil" if args
|
211
|
-
return "Invalid job payload, args must be an Array, not #{args.class.name}"
|
224
|
+
return "Invalid job payload, args is nil" if args.nil?
|
225
|
+
return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
|
212
226
|
|
213
227
|
begin
|
214
|
-
args.map
|
228
|
+
args.map { |arg|
|
215
229
|
h(truncate(to_display(arg), truncate_after_chars))
|
216
|
-
|
230
|
+
}.join(", ")
|
217
231
|
rescue
|
218
232
|
"Illegal job arguments: #{h args.inspect}"
|
219
233
|
end
|
220
234
|
end
|
221
235
|
|
222
236
|
def csrf_tag
|
223
|
-
"<input type='hidden' name='authenticity_token' value='#{
|
237
|
+
"<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
|
224
238
|
end
|
225
239
|
|
226
240
|
def to_display(arg)
|
241
|
+
arg.inspect
|
242
|
+
rescue
|
227
243
|
begin
|
228
|
-
arg.
|
229
|
-
rescue
|
230
|
-
|
231
|
-
arg.to_s
|
232
|
-
rescue => ex
|
233
|
-
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
234
|
-
end
|
244
|
+
arg.to_s
|
245
|
+
rescue => ex
|
246
|
+
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
235
247
|
end
|
236
248
|
end
|
237
249
|
|
238
|
-
RETRY_JOB_KEYS = Set.new(%w
|
250
|
+
RETRY_JOB_KEYS = Set.new(%w[
|
239
251
|
queue class args retry_count retried_at failed_at
|
240
252
|
jid error_message error_class backtrace
|
241
253
|
error_backtrace enqueued_at retry wrapped
|
242
|
-
created_at
|
243
|
-
)
|
254
|
+
created_at tags display_class
|
255
|
+
])
|
244
256
|
|
245
257
|
def retry_extra_items(retry_job)
|
246
258
|
@retry_extra_items ||= {}.tap do |extra|
|
@@ -250,15 +262,29 @@ module Sidekiq
|
|
250
262
|
end
|
251
263
|
end
|
252
264
|
|
265
|
+
def format_memory(rss_kb)
|
266
|
+
return "0" if rss_kb.nil? || rss_kb == 0
|
267
|
+
|
268
|
+
if rss_kb < 100_000
|
269
|
+
"#{number_with_delimiter(rss_kb)} KB"
|
270
|
+
elsif rss_kb < 10_000_000
|
271
|
+
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
272
|
+
else
|
273
|
+
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)).round(1))} GB"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
253
277
|
def number_with_delimiter(number)
|
278
|
+
return "" if number.nil?
|
279
|
+
|
254
280
|
begin
|
255
281
|
Float(number)
|
256
282
|
rescue ArgumentError, TypeError
|
257
283
|
return number
|
258
284
|
end
|
259
285
|
|
260
|
-
options = {delimiter:
|
261
|
-
parts = number.to_s.to_str.split(
|
286
|
+
options = {delimiter: ",", separator: "."}
|
287
|
+
parts = number.to_s.to_str.split(".")
|
262
288
|
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
|
263
289
|
parts.join(options[:separator])
|
264
290
|
end
|
@@ -266,8 +292,8 @@ module Sidekiq
|
|
266
292
|
def h(text)
|
267
293
|
::Rack::Utils.escape_html(text)
|
268
294
|
rescue ArgumentError => e
|
269
|
-
raise unless e.message.eql?(
|
270
|
-
text.encode!(
|
295
|
+
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
296
|
+
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
271
297
|
retry
|
272
298
|
end
|
273
299
|
|
@@ -284,7 +310,7 @@ module Sidekiq
|
|
284
310
|
end
|
285
311
|
|
286
312
|
def environment_title_prefix
|
287
|
-
environment = Sidekiq.
|
313
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
288
314
|
|
289
315
|
"[#{environment.upcase}] " unless environment == "production"
|
290
316
|
end
|
@@ -294,30 +320,27 @@ module Sidekiq
|
|
294
320
|
end
|
295
321
|
|
296
322
|
def server_utc_time
|
297
|
-
Time.now.utc.strftime(
|
323
|
+
Time.now.utc.strftime("%H:%M:%S UTC")
|
298
324
|
end
|
299
325
|
|
300
|
-
def
|
301
|
-
|
302
|
-
namespace_suffix = namespace == nil ? '' : "##{namespace}"
|
303
|
-
"#{redis_connection}#{namespace_suffix}"
|
304
|
-
end
|
326
|
+
def pollable?
|
327
|
+
!(current_path == "" || current_path.start_with?("metrics"))
|
305
328
|
end
|
306
329
|
|
307
330
|
def retry_or_delete_or_kill(job, params)
|
308
|
-
if params[
|
331
|
+
if params["retry"]
|
309
332
|
job.retry
|
310
|
-
elsif params[
|
333
|
+
elsif params["delete"]
|
311
334
|
job.delete
|
312
|
-
elsif params[
|
335
|
+
elsif params["kill"]
|
313
336
|
job.kill
|
314
337
|
end
|
315
338
|
end
|
316
339
|
|
317
340
|
def delete_or_add_queue(job, params)
|
318
|
-
if params[
|
341
|
+
if params["delete"]
|
319
342
|
job.delete
|
320
|
-
elsif params[
|
343
|
+
elsif params["add_to_queue"]
|
321
344
|
job.add_to_queue
|
322
345
|
end
|
323
346
|
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
|