sidekiq 5.1.1 → 7.1.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 +5 -5
- data/Changes.md +627 -8
- data/LICENSE.txt +9 -0
- data/README.md +47 -50
- 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 +566 -329
- data/lib/sidekiq/capsule.rb +127 -0
- data/lib/sidekiq/cli.rb +241 -256
- data/lib/sidekiq/client.rb +125 -102
- data/lib/sidekiq/component.rb +68 -0
- data/lib/sidekiq/config.rb +278 -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 +36 -9
- data/lib/sidekiq/job_retry.rb +147 -98
- data/lib/sidekiq/job_util.rb +105 -0
- data/lib/sidekiq/launcher.rb +207 -103
- data/lib/sidekiq/logger.rb +131 -0
- data/lib/sidekiq/manager.rb +43 -47
- data/lib/sidekiq/metrics/query.rb +153 -0
- data/lib/sidekiq/metrics/shared.rb +95 -0
- data/lib/sidekiq/metrics/tracking.rb +136 -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 +159 -107
- data/lib/sidekiq/rails.rb +54 -43
- data/lib/sidekiq/redis_client_adapter.rb +96 -0
- data/lib/sidekiq/redis_connection.rb +39 -81
- data/lib/sidekiq/ring_buffer.rb +29 -0
- data/lib/sidekiq/scheduled.rb +139 -48
- 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 +70 -88
- 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 +143 -77
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +144 -106
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +60 -111
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +94 -183
- data/sidekiq.gemspec +25 -23
- 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 -282
- data/web/assets/javascripts/metrics.js +264 -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 +134 -521
- data/web/assets/stylesheets/bootstrap.css +2 -2
- data/web/locales/ar.yml +71 -64
- 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 +84 -65
- 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 +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 +8 -2
- data/web/views/_job_info.erb +21 -4
- data/web/views/_metrics_period_select.erb +12 -0
- data/web/views/_nav.erb +4 -18
- 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 +75 -25
- data/web/views/dashboard.erb +58 -18
- data/web/views/dead.erb +3 -3
- data/web/views/layout.erb +4 -2
- data/web/views/metrics.erb +82 -0
- data/web/views/metrics_for_job.erb +68 -0
- data/web/views/morgue.erb +14 -15
- data/web/views/queue.erb +33 -23
- data/web/views/queues.erb +14 -4
- data/web/views/retries.erb +19 -16
- data/web/views/retry.erb +3 -3
- data/web/views/scheduled.erb +17 -15
- metadata +71 -140
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -13
- data/.travis.yml +0 -14
- 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 -95
- data/Ent-Changes.md +0 -210
- data/Gemfile +0 -8
- 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 -716
- data/Rakefile +0 -8
- data/bin/sidekiqctl +0 -99
- 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/delay.rb +0 -41
- 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 -22
- data/lib/sidekiq/middleware/server/active_record_cache.rb +0 -11
- data/lib/sidekiq/util.rb +0 -66
- data/lib/sidekiq/worker.rb +0 -204
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.read(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
|
-
#
|
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
|
+
|
121
|
+
# sidekiq/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] || msg
|
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,111 +136,131 @@ 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
|
-
|
146
|
-
|
147
|
-
|
164
|
+
def busy_weights(capsule_weights)
|
165
|
+
# backwards compat with 7.0.0, remove in 7.1
|
166
|
+
cw = [capsule_weights].flatten
|
167
|
+
cw.map { |hash|
|
168
|
+
hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
|
169
|
+
}.join("; ")
|
148
170
|
end
|
149
171
|
|
150
|
-
def
|
151
|
-
Sidekiq.
|
152
|
-
c = conn.connection
|
153
|
-
"redis://#{c[:location]}/#{c[:db]}"
|
154
|
-
end
|
172
|
+
def stats
|
173
|
+
@stats ||= Sidekiq::Stats.new
|
155
174
|
end
|
156
175
|
|
157
|
-
def
|
158
|
-
|
176
|
+
def redis_url
|
177
|
+
Sidekiq.redis do |conn|
|
178
|
+
conn.config.server_url
|
179
|
+
end
|
159
180
|
end
|
160
181
|
|
161
182
|
def redis_info
|
162
|
-
Sidekiq.redis_info
|
183
|
+
Sidekiq.default_configuration.redis_info
|
163
184
|
end
|
164
185
|
|
165
186
|
def root_path
|
166
|
-
"#{env[
|
187
|
+
"#{env["SCRIPT_NAME"]}/"
|
167
188
|
end
|
168
189
|
|
169
190
|
def current_path
|
170
|
-
@current_path ||= request.path_info.gsub(/^\//,
|
191
|
+
@current_path ||= request.path_info.gsub(/^\//, "")
|
171
192
|
end
|
172
193
|
|
173
194
|
def current_status
|
174
|
-
|
195
|
+
(workset.size == 0) ? "idle" : "active"
|
175
196
|
end
|
176
197
|
|
177
198
|
def relative_time(time)
|
178
199
|
stamp = time.getutc.iso8601
|
179
|
-
%
|
200
|
+
%(<time class="ltr" dir="ltr" title="#{stamp}" datetime="#{stamp}">#{time}</time>)
|
180
201
|
end
|
181
202
|
|
182
203
|
def job_params(job, score)
|
183
|
-
"#{score}-#{job[
|
204
|
+
"#{score}-#{job["jid"]}"
|
184
205
|
end
|
185
206
|
|
186
207
|
def parse_params(params)
|
187
|
-
score, jid = params.split("-")
|
208
|
+
score, jid = params.split("-", 2)
|
188
209
|
[score.to_f, jid]
|
189
210
|
end
|
190
211
|
|
191
|
-
SAFE_QPARAMS = %w
|
212
|
+
SAFE_QPARAMS = %w[page direction]
|
192
213
|
|
193
214
|
# Merge options with current params, filter safe params, and stringify to query string
|
194
215
|
def qparams(options)
|
195
|
-
|
196
|
-
options.keys.each do |key|
|
197
|
-
options[key.to_s] = options.delete(key)
|
198
|
-
end
|
216
|
+
stringified_options = options.transform_keys(&:to_s)
|
199
217
|
|
200
|
-
params.merge(
|
218
|
+
to_query_string(params.merge(stringified_options))
|
219
|
+
end
|
220
|
+
|
221
|
+
def to_query_string(params)
|
222
|
+
params.map { |key, value|
|
201
223
|
SAFE_QPARAMS.include?(key) ? "#{key}=#{CGI.escape(value.to_s)}" : next
|
202
|
-
|
224
|
+
}.compact.join("&")
|
203
225
|
end
|
204
226
|
|
205
227
|
def truncate(text, truncate_after_chars = 2000)
|
206
|
-
truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
|
228
|
+
(truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
|
207
229
|
end
|
208
230
|
|
209
231
|
def display_args(args, truncate_after_chars = 2000)
|
210
|
-
args
|
211
|
-
|
212
|
-
|
232
|
+
return "Invalid job payload, args is nil" if args.nil?
|
233
|
+
return "Invalid job payload, args must be an Array, not #{args.class.name}" unless args.is_a?(Array)
|
234
|
+
|
235
|
+
begin
|
236
|
+
args.map { |arg|
|
237
|
+
h(truncate(to_display(arg), truncate_after_chars))
|
238
|
+
}.join(", ")
|
239
|
+
rescue
|
240
|
+
"Illegal job arguments: #{h args.inspect}"
|
241
|
+
end
|
213
242
|
end
|
214
243
|
|
215
244
|
def csrf_tag
|
216
|
-
"<input type='hidden' name='authenticity_token' value='#{
|
245
|
+
"<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
|
217
246
|
end
|
218
247
|
|
219
248
|
def to_display(arg)
|
249
|
+
arg.inspect
|
250
|
+
rescue
|
220
251
|
begin
|
221
|
-
arg.
|
222
|
-
rescue
|
223
|
-
|
224
|
-
arg.to_s
|
225
|
-
rescue => ex
|
226
|
-
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
227
|
-
end
|
252
|
+
arg.to_s
|
253
|
+
rescue => ex
|
254
|
+
"Cannot display argument: [#{ex.class.name}] #{ex.message}"
|
228
255
|
end
|
229
256
|
end
|
230
257
|
|
231
|
-
RETRY_JOB_KEYS = Set.new(%w
|
258
|
+
RETRY_JOB_KEYS = Set.new(%w[
|
232
259
|
queue class args retry_count retried_at failed_at
|
233
260
|
jid error_message error_class backtrace
|
234
261
|
error_backtrace enqueued_at retry wrapped
|
235
|
-
created_at
|
236
|
-
)
|
262
|
+
created_at tags display_class
|
263
|
+
])
|
237
264
|
|
238
265
|
def retry_extra_items(retry_job)
|
239
266
|
@retry_extra_items ||= {}.tap do |extra|
|
@@ -243,15 +270,29 @@ module Sidekiq
|
|
243
270
|
end
|
244
271
|
end
|
245
272
|
|
273
|
+
def format_memory(rss_kb)
|
274
|
+
return "0" if rss_kb.nil? || rss_kb == 0
|
275
|
+
|
276
|
+
if rss_kb < 100_000
|
277
|
+
"#{number_with_delimiter(rss_kb)} KB"
|
278
|
+
elsif rss_kb < 10_000_000
|
279
|
+
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
280
|
+
else
|
281
|
+
"#{number_with_delimiter((rss_kb / (1024.0 * 1024.0)).round(1))} GB"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
246
285
|
def number_with_delimiter(number)
|
286
|
+
return "" if number.nil?
|
287
|
+
|
247
288
|
begin
|
248
289
|
Float(number)
|
249
290
|
rescue ArgumentError, TypeError
|
250
291
|
return number
|
251
292
|
end
|
252
293
|
|
253
|
-
options = {delimiter:
|
254
|
-
parts = number.to_s.to_str.split(
|
294
|
+
options = {delimiter: ",", separator: "."}
|
295
|
+
parts = number.to_s.to_str.split(".")
|
255
296
|
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
|
256
297
|
parts.join(options[:separator])
|
257
298
|
end
|
@@ -259,8 +300,8 @@ module Sidekiq
|
|
259
300
|
def h(text)
|
260
301
|
::Rack::Utils.escape_html(text)
|
261
302
|
rescue ArgumentError => e
|
262
|
-
raise unless e.message.eql?(
|
263
|
-
text.encode!(
|
303
|
+
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
304
|
+
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
264
305
|
retry
|
265
306
|
end
|
266
307
|
|
@@ -277,7 +318,7 @@ module Sidekiq
|
|
277
318
|
end
|
278
319
|
|
279
320
|
def environment_title_prefix
|
280
|
-
environment = Sidekiq.
|
321
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
281
322
|
|
282
323
|
"[#{environment.upcase}] " unless environment == "production"
|
283
324
|
end
|
@@ -287,30 +328,27 @@ module Sidekiq
|
|
287
328
|
end
|
288
329
|
|
289
330
|
def server_utc_time
|
290
|
-
Time.now.utc.strftime(
|
331
|
+
Time.now.utc.strftime("%H:%M:%S UTC")
|
291
332
|
end
|
292
333
|
|
293
|
-
def
|
294
|
-
|
295
|
-
namespace_suffix = namespace == nil ? '' : "##{namespace}"
|
296
|
-
"#{redis_connection}#{namespace_suffix}"
|
297
|
-
end
|
334
|
+
def pollable?
|
335
|
+
!(current_path == "" || current_path.start_with?("metrics"))
|
298
336
|
end
|
299
337
|
|
300
338
|
def retry_or_delete_or_kill(job, params)
|
301
|
-
if params[
|
339
|
+
if params["retry"]
|
302
340
|
job.retry
|
303
|
-
elsif params[
|
341
|
+
elsif params["delete"]
|
304
342
|
job.delete
|
305
|
-
elsif params[
|
343
|
+
elsif params["kill"]
|
306
344
|
job.kill
|
307
345
|
end
|
308
346
|
end
|
309
347
|
|
310
348
|
def delete_or_add_queue(job, params)
|
311
|
-
if params[
|
349
|
+
if params["delete"]
|
312
350
|
job.delete
|
313
|
-
elsif params[
|
351
|
+
elsif params["add_to_queue"]
|
314
352
|
job.add_to_queue
|
315
353
|
end
|
316
354
|
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
|