sidekiq 5.2.10 → 6.5.6
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 +391 -1
- data/LICENSE +3 -3
- data/README.md +24 -35
- data/bin/sidekiq +27 -3
- data/bin/sidekiqload +79 -67
- 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 +504 -307
- data/lib/sidekiq/cli.rb +190 -206
- data/lib/sidekiq/client.rb +77 -81
- data/lib/sidekiq/component.rb +65 -0
- data/lib/sidekiq/delay.rb +8 -7
- data/lib/sidekiq/extensions/action_mailer.rb +13 -22
- data/lib/sidekiq/extensions/active_record.rb +13 -10
- data/lib/sidekiq/extensions/class_methods.rb +14 -11
- data/lib/sidekiq/extensions/generic_proxy.rb +7 -5
- data/lib/sidekiq/fetch.rb +50 -40
- data/lib/sidekiq/job.rb +13 -0
- data/lib/sidekiq/job_logger.rb +33 -7
- data/lib/sidekiq/job_retry.rb +126 -106
- data/lib/sidekiq/job_util.rb +71 -0
- data/lib/sidekiq/launcher.rb +177 -83
- data/lib/sidekiq/logger.rb +156 -0
- data/lib/sidekiq/manager.rb +40 -41
- data/lib/sidekiq/metrics/deploy.rb +47 -0
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +94 -0
- data/lib/sidekiq/metrics/tracking.rb +134 -0
- data/lib/sidekiq/middleware/chain.rb +102 -46
- data/lib/sidekiq/middleware/current_attributes.rb +63 -0
- data/lib/sidekiq/middleware/i18n.rb +7 -7
- data/lib/sidekiq/middleware/modules.rb +21 -0
- data/lib/sidekiq/monitor.rb +133 -0
- data/lib/sidekiq/paginator.rb +20 -16
- data/lib/sidekiq/processor.rb +104 -97
- data/lib/sidekiq/rails.rb +47 -37
- data/lib/sidekiq/redis_client_adapter.rb +154 -0
- data/lib/sidekiq/redis_connection.rb +108 -77
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +64 -35
- 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 +68 -58
- data/lib/sidekiq/transaction_aware_client.rb +45 -0
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +100 -77
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +134 -94
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +65 -105
- data/lib/sidekiq/worker.rb +253 -106
- data/lib/sidekiq.rb +170 -62
- data/sidekiq.gemspec +23 -16
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +112 -61
- 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.js +53 -89
- data/web/assets/javascripts/graph.js +16 -0
- data/web/assets/javascripts/metrics.js +262 -0
- data/web/assets/stylesheets/application-dark.css +143 -0
- data/web/assets/stylesheets/application-rtl.css +0 -4
- data/web/assets/stylesheets/application.css +88 -233
- data/web/locales/ar.yml +8 -2
- data/web/locales/de.yml +14 -2
- data/web/locales/el.yml +43 -19
- data/web/locales/en.yml +13 -1
- data/web/locales/es.yml +18 -2
- data/web/locales/fr.yml +10 -3
- data/web/locales/ja.yml +7 -1
- data/web/locales/lt.yml +83 -0
- data/web/locales/pl.yml +4 -4
- data/web/locales/pt-br.yml +27 -9
- data/web/locales/ru.yml +4 -0
- data/web/locales/vi.yml +83 -0
- data/web/views/_footer.erb +1 -1
- data/web/views/_job_info.erb +3 -2
- data/web/views/_nav.erb +1 -1
- data/web/views/_poll_link.erb +2 -5
- data/web/views/_summary.erb +7 -7
- data/web/views/busy.erb +56 -22
- data/web/views/dashboard.erb +23 -14
- data/web/views/dead.erb +3 -3
- data/web/views/layout.erb +3 -1
- data/web/views/metrics.erb +69 -0
- data/web/views/metrics_for_job.erb +87 -0
- data/web/views/morgue.erb +9 -6
- data/web/views/queue.erb +23 -10
- data/web/views/queues.erb +10 -2
- data/web/views/retries.erb +11 -8
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +5 -2
- metadata +53 -64
- 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 -19
- 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/exception_handler.rb +0 -29
- 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/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,28 +136,48 @@ 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 so that
|
152
|
+
# 'worker.1' < 'worker.2' < 'worker.10' < 'worker.20'
|
153
|
+
# '2.1.1.1' < '192.168.0.2' < '192.168.0.10'
|
154
|
+
def sorted_processes
|
155
|
+
@sorted_processes ||= begin
|
156
|
+
return processes unless processes.all? { |p| p["hostname"] }
|
157
|
+
|
158
|
+
split_characters = /[._-]/
|
159
|
+
|
160
|
+
padding = processes.flat_map { |p| p["hostname"].split(split_characters) }.map(&:size).max
|
161
|
+
|
162
|
+
processes.to_a.sort_by do |process|
|
163
|
+
process["hostname"].split(split_characters).map do |substring|
|
164
|
+
# Left-pad the substring with '0' if it starts with a number or 'a'
|
165
|
+
# otherwise, so that '25' < 192' < 'a' ('025' < '192' < 'aaa')
|
166
|
+
padding_char = substring[0].match?(/\d/) ? "0" : "a"
|
167
|
+
|
168
|
+
substring.rjust(padding, padding_char)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
142
172
|
end
|
143
173
|
|
144
|
-
def
|
145
|
-
Sidekiq.
|
146
|
-
conn.zrangebyscore('retry', score, score)
|
147
|
-
end.map { |msg| Sidekiq.load_json(msg) }
|
174
|
+
def stats
|
175
|
+
@stats ||= Sidekiq::Stats.new
|
148
176
|
end
|
149
177
|
|
150
178
|
def redis_connection
|
151
179
|
Sidekiq.redis do |conn|
|
152
|
-
|
153
|
-
"redis://#{c[:location]}/#{c[:db]}"
|
180
|
+
conn.connection[:id]
|
154
181
|
end
|
155
182
|
end
|
156
183
|
|
@@ -163,24 +190,24 @@ module Sidekiq
|
|
163
190
|
end
|
164
191
|
|
165
192
|
def root_path
|
166
|
-
"#{env[
|
193
|
+
"#{env["SCRIPT_NAME"]}/"
|
167
194
|
end
|
168
195
|
|
169
196
|
def current_path
|
170
|
-
@current_path ||= request.path_info.gsub(/^\//,
|
197
|
+
@current_path ||= request.path_info.gsub(/^\//, "")
|
171
198
|
end
|
172
199
|
|
173
200
|
def current_status
|
174
|
-
|
201
|
+
workset.size == 0 ? "idle" : "active"
|
175
202
|
end
|
176
203
|
|
177
204
|
def relative_time(time)
|
178
205
|
stamp = time.getutc.iso8601
|
179
|
-
%
|
206
|
+
%(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
|
180
207
|
end
|
181
208
|
|
182
209
|
def job_params(job, score)
|
183
|
-
"#{score}-#{job[
|
210
|
+
"#{score}-#{job["jid"]}"
|
184
211
|
end
|
185
212
|
|
186
213
|
def parse_params(params)
|
@@ -188,18 +215,19 @@ module Sidekiq
|
|
188
215
|
[score.to_f, jid]
|
189
216
|
end
|
190
217
|
|
191
|
-
SAFE_QPARAMS = %w
|
218
|
+
SAFE_QPARAMS = %w[page direction]
|
192
219
|
|
193
220
|
# Merge options with current params, filter safe params, and stringify to query string
|
194
221
|
def qparams(options)
|
195
|
-
|
196
|
-
options.keys.each do |key|
|
197
|
-
options[key.to_s] = options.delete(key)
|
198
|
-
end
|
222
|
+
stringified_options = options.transform_keys(&:to_s)
|
199
223
|
|
200
|
-
params.merge(
|
224
|
+
to_query_string(params.merge(stringified_options))
|
225
|
+
end
|
226
|
+
|
227
|
+
def to_query_string(params)
|
228
|
+
params.map { |key, value|
|
201
229
|
SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
|
202
|
-
|
230
|
+
}.compact.join("&")
|
203
231
|
end
|
204
232
|
|
205
233
|
def truncate(text, truncate_after_chars = 2000)
|
@@ -207,40 +235,38 @@ module Sidekiq
|
|
207
235
|
end
|
208
236
|
|
209
237
|
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}"
|
238
|
+
return "Invalid job payload, args is nil" if args.nil?
|
239
|
+
return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
|
212
240
|
|
213
241
|
begin
|
214
|
-
args.map
|
242
|
+
args.map { |arg|
|
215
243
|
h(truncate(to_display(arg), truncate_after_chars))
|
216
|
-
|
244
|
+
}.join(", ")
|
217
245
|
rescue
|
218
246
|
"Illegal job arguments: #{h args.inspect}"
|
219
247
|
end
|
220
248
|
end
|
221
249
|
|
222
250
|
def csrf_tag
|
223
|
-
"<input type='hidden' name='authenticity_token' value='#{
|
251
|
+
"<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
|
224
252
|
end
|
225
253
|
|
226
254
|
def to_display(arg)
|
255
|
+
arg.inspect
|
256
|
+
rescue
|
227
257
|
begin
|
228
|
-
arg.
|
229
|
-
rescue
|
230
|
-
|
231
|
-
arg.to_s
|
232
|
-
rescue => ex
|
233
|
-
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
234
|
-
end
|
258
|
+
arg.to_s
|
259
|
+
rescue => ex
|
260
|
+
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
235
261
|
end
|
236
262
|
end
|
237
263
|
|
238
|
-
RETRY_JOB_KEYS = Set.new(%w
|
264
|
+
RETRY_JOB_KEYS = Set.new(%w[
|
239
265
|
queue class args retry_count retried_at failed_at
|
240
266
|
jid error_message error_class backtrace
|
241
267
|
error_backtrace enqueued_at retry wrapped
|
242
|
-
created_at
|
243
|
-
)
|
268
|
+
created_at tags display_class
|
269
|
+
])
|
244
270
|
|
245
271
|
def retry_extra_items(retry_job)
|
246
272
|
@retry_extra_items ||= {}.tap do |extra|
|
@@ -250,15 +276,29 @@ module Sidekiq
|
|
250
276
|
end
|
251
277
|
end
|
252
278
|
|
279
|
+
def format_memory(rss_kb)
|
280
|
+
return "0" if rss_kb.nil? || rss_kb == 0
|
281
|
+
|
282
|
+
if rss_kb < 100_000
|
283
|
+
"#{number_with_delimiter(rss_kb)} KB"
|
284
|
+
elsif rss_kb < 10_000_000
|
285
|
+
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
286
|
+
else
|
287
|
+
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)).round(1))} GB"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
253
291
|
def number_with_delimiter(number)
|
292
|
+
return "" if number.nil?
|
293
|
+
|
254
294
|
begin
|
255
295
|
Float(number)
|
256
296
|
rescue ArgumentError, TypeError
|
257
297
|
return number
|
258
298
|
end
|
259
299
|
|
260
|
-
options = {delimiter:
|
261
|
-
parts = number.to_s.to_str.split(
|
300
|
+
options = {delimiter: ",", separator: "."}
|
301
|
+
parts = number.to_s.to_str.split(".")
|
262
302
|
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
|
263
303
|
parts.join(options[:separator])
|
264
304
|
end
|
@@ -266,8 +306,8 @@ module Sidekiq
|
|
266
306
|
def h(text)
|
267
307
|
::Rack::Utils.escape_html(text)
|
268
308
|
rescue ArgumentError => e
|
269
|
-
raise unless e.message.eql?(
|
270
|
-
text.encode!(
|
309
|
+
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
310
|
+
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
271
311
|
retry
|
272
312
|
end
|
273
313
|
|
@@ -284,7 +324,7 @@ module Sidekiq
|
|
284
324
|
end
|
285
325
|
|
286
326
|
def environment_title_prefix
|
287
|
-
environment = Sidekiq
|
327
|
+
environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
288
328
|
|
289
329
|
"[#{environment.upcase}] " unless environment == "production"
|
290
330
|
end
|
@@ -294,30 +334,30 @@ module Sidekiq
|
|
294
334
|
end
|
295
335
|
|
296
336
|
def server_utc_time
|
297
|
-
Time.now.utc.strftime(
|
337
|
+
Time.now.utc.strftime("%H:%M:%S UTC")
|
298
338
|
end
|
299
339
|
|
300
340
|
def redis_connection_and_namespace
|
301
341
|
@redis_connection_and_namespace ||= begin
|
302
|
-
namespace_suffix = namespace
|
342
|
+
namespace_suffix = namespace.nil? ? "" : "##{namespace}"
|
303
343
|
"#{redis_connection}#{namespace_suffix}"
|
304
344
|
end
|
305
345
|
end
|
306
346
|
|
307
347
|
def retry_or_delete_or_kill(job, params)
|
308
|
-
if params[
|
348
|
+
if params["retry"]
|
309
349
|
job.retry
|
310
|
-
elsif params[
|
350
|
+
elsif params["delete"]
|
311
351
|
job.delete
|
312
|
-
elsif params[
|
352
|
+
elsif params["kill"]
|
313
353
|
job.kill
|
314
354
|
end
|
315
355
|
end
|
316
356
|
|
317
357
|
def delete_or_add_queue(job, params)
|
318
|
-
if params[
|
358
|
+
if params["delete"]
|
319
359
|
job.delete
|
320
|
-
elsif params[
|
360
|
+
elsif params["add_to_queue"]
|
321
361
|
job.add_to_queue
|
322
362
|
end
|
323
363
|
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
|