sidekiq 6.5.8 → 7.3.10
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 +359 -15
- data/README.md +43 -35
- data/bin/multi_queue_bench +271 -0
- data/bin/sidekiq +3 -8
- data/bin/sidekiqload +213 -118
- data/bin/sidekiqmon +3 -0
- data/lib/active_job/queue_adapters/sidekiq_adapter.rb +75 -0
- data/lib/generators/sidekiq/job_generator.rb +2 -0
- data/lib/sidekiq/api.rb +243 -162
- data/lib/sidekiq/capsule.rb +132 -0
- data/lib/sidekiq/cli.rb +61 -75
- data/lib/sidekiq/client.rb +88 -39
- data/lib/sidekiq/component.rb +26 -1
- data/lib/sidekiq/config.rb +311 -0
- data/lib/sidekiq/deploy.rb +64 -0
- data/lib/sidekiq/embedded.rb +63 -0
- data/lib/sidekiq/fetch.rb +12 -14
- data/lib/sidekiq/iterable_job.rb +55 -0
- data/lib/sidekiq/job/interrupt_handler.rb +24 -0
- data/lib/sidekiq/job/iterable/active_record_enumerator.rb +53 -0
- data/lib/sidekiq/job/iterable/csv_enumerator.rb +47 -0
- data/lib/sidekiq/job/iterable/enumerators.rb +135 -0
- data/lib/sidekiq/job/iterable.rb +294 -0
- data/lib/sidekiq/job.rb +382 -10
- data/lib/sidekiq/job_logger.rb +8 -7
- data/lib/sidekiq/job_retry.rb +42 -19
- data/lib/sidekiq/job_util.rb +53 -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 +10 -5
- data/lib/sidekiq/metrics/shared.rb +21 -9
- data/lib/sidekiq/metrics/tracking.rb +40 -26
- data/lib/sidekiq/middleware/chain.rb +19 -18
- data/lib/sidekiq/middleware/current_attributes.rb +85 -20
- data/lib/sidekiq/middleware/i18n.rb +2 -0
- data/lib/sidekiq/middleware/modules.rb +2 -0
- data/lib/sidekiq/monitor.rb +19 -5
- data/lib/sidekiq/paginator.rb +10 -4
- data/lib/sidekiq/processor.rb +62 -57
- data/lib/sidekiq/rails.rb +32 -16
- data/lib/sidekiq/redis_client_adapter.rb +31 -71
- data/lib/sidekiq/redis_connection.rb +54 -114
- data/lib/sidekiq/ring_buffer.rb +3 -0
- data/lib/sidekiq/scheduled.rb +22 -23
- data/lib/sidekiq/systemd.rb +2 -0
- data/lib/sidekiq/testing.rb +37 -46
- data/lib/sidekiq/transaction_aware_client.rb +23 -9
- data/lib/sidekiq/version.rb +6 -1
- data/lib/sidekiq/web/action.rb +29 -7
- data/lib/sidekiq/web/application.rb +84 -30
- data/lib/sidekiq/web/csrf_protection.rb +10 -7
- data/lib/sidekiq/web/helpers.rb +113 -52
- data/lib/sidekiq/web/router.rb +5 -2
- data/lib/sidekiq/web.rb +70 -17
- data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
- data/lib/sidekiq.rb +78 -274
- data/sidekiq.gemspec +13 -10
- data/web/assets/javascripts/application.js +45 -0
- data/web/assets/javascripts/base-charts.js +106 -0
- data/web/assets/javascripts/dashboard-charts.js +194 -0
- data/web/assets/javascripts/dashboard.js +17 -233
- 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 +56 -296
- 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 +81 -71
- data/web/locales/es.yml +68 -68
- data/web/locales/fa.yml +65 -65
- data/web/locales/fr.yml +80 -67
- data/web/locales/gd.yml +98 -0
- data/web/locales/he.yml +65 -64
- data/web/locales/hi.yml +59 -59
- data/web/locales/it.yml +85 -54
- data/web/locales/ja.yml +67 -70
- 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 +78 -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/tr.yml +100 -0
- data/web/locales/uk.yml +85 -61
- data/web/locales/ur.yml +64 -64
- data/web/locales/vi.yml +67 -67
- data/web/locales/zh-cn.yml +20 -19
- data/web/locales/zh-tw.yml +10 -2
- data/web/views/_footer.erb +16 -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 +32 -8
- data/web/views/filtering.erb +6 -0
- data/web/views/layout.erb +6 -6
- data/web/views/metrics.erb +47 -26
- data/web/views/metrics_for_job.erb +43 -71
- data/web/views/morgue.erb +7 -11
- data/web/views/queue.erb +11 -15
- data/web/views/queues.erb +9 -3
- data/web/views/retries.erb +5 -9
- data/web/views/scheduled.erb +12 -13
- metadata +81 -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
data/lib/sidekiq/web/helpers.rb
CHANGED
|
@@ -6,21 +6,68 @@ require "yaml"
|
|
|
6
6
|
require "cgi"
|
|
7
7
|
|
|
8
8
|
module Sidekiq
|
|
9
|
-
#
|
|
9
|
+
# These methods are available to pages within the Web UI and UI extensions.
|
|
10
|
+
# They are not public APIs for applications to use.
|
|
10
11
|
module WebHelpers
|
|
12
|
+
def style_tag(location, **kwargs)
|
|
13
|
+
global = location.match?(/:\/\//)
|
|
14
|
+
location = root_path + location if !global && !location.start_with?(root_path)
|
|
15
|
+
attrs = {
|
|
16
|
+
type: "text/css",
|
|
17
|
+
media: "screen",
|
|
18
|
+
rel: "stylesheet",
|
|
19
|
+
nonce: csp_nonce,
|
|
20
|
+
href: location
|
|
21
|
+
}
|
|
22
|
+
html_tag(:link, attrs.merge(kwargs))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def script_tag(location, **kwargs)
|
|
26
|
+
global = location.match?(/:\/\//)
|
|
27
|
+
location = root_path + location if !global && !location.start_with?(root_path)
|
|
28
|
+
attrs = {
|
|
29
|
+
type: "text/javascript",
|
|
30
|
+
nonce: csp_nonce,
|
|
31
|
+
src: location
|
|
32
|
+
}
|
|
33
|
+
html_tag(:script, attrs.merge(kwargs)) {}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# NB: keys and values are not escaped; do not allow user input
|
|
37
|
+
# in the attributes
|
|
38
|
+
private def html_tag(tagname, attrs)
|
|
39
|
+
s = +"<#{tagname}"
|
|
40
|
+
attrs.each_pair do |k, v|
|
|
41
|
+
next unless v
|
|
42
|
+
s << " #{k}=\"#{v}\""
|
|
43
|
+
end
|
|
44
|
+
if block_given?
|
|
45
|
+
s << ">"
|
|
46
|
+
yield s
|
|
47
|
+
s << "</#{tagname}>"
|
|
48
|
+
else
|
|
49
|
+
s << " />"
|
|
50
|
+
end
|
|
51
|
+
s
|
|
52
|
+
end
|
|
53
|
+
|
|
11
54
|
def strings(lang)
|
|
12
|
-
|
|
55
|
+
@@strings ||= {}
|
|
13
56
|
|
|
14
57
|
# Allow sidekiq-web extensions to add locale paths
|
|
15
58
|
# so extensions can be localized
|
|
16
|
-
|
|
59
|
+
@@strings[lang] ||= settings.locales.each_with_object({}) do |path, global|
|
|
17
60
|
find_locale_files(lang).each do |file|
|
|
18
|
-
strs = YAML.safe_load(File.
|
|
61
|
+
strs = YAML.safe_load(File.read(file))
|
|
19
62
|
global.merge!(strs[lang])
|
|
20
63
|
end
|
|
21
64
|
end
|
|
22
65
|
end
|
|
23
66
|
|
|
67
|
+
def to_json(x)
|
|
68
|
+
Sidekiq.dump_json(x)
|
|
69
|
+
end
|
|
70
|
+
|
|
24
71
|
def singularize(str, count)
|
|
25
72
|
if count == 1 && str.respond_to?(:singularize) # rails
|
|
26
73
|
str.singularize
|
|
@@ -30,27 +77,48 @@ module Sidekiq
|
|
|
30
77
|
end
|
|
31
78
|
|
|
32
79
|
def clear_caches
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
80
|
+
@@strings = nil
|
|
81
|
+
@@locale_files = nil
|
|
82
|
+
@@available_locales = nil
|
|
36
83
|
end
|
|
37
84
|
|
|
38
85
|
def locale_files
|
|
39
|
-
|
|
86
|
+
@@locale_files ||= settings.locales.flat_map { |path|
|
|
40
87
|
Dir["#{path}/*.yml"]
|
|
41
88
|
}
|
|
42
89
|
end
|
|
43
90
|
|
|
44
91
|
def available_locales
|
|
45
|
-
|
|
92
|
+
@@available_locales ||= Set.new(locale_files.map { |path| File.basename(path, ".yml") })
|
|
46
93
|
end
|
|
47
94
|
|
|
48
95
|
def find_locale_files(lang)
|
|
49
96
|
locale_files.select { |file| file =~ /\/#{lang}\.yml$/ }
|
|
50
97
|
end
|
|
51
98
|
|
|
52
|
-
|
|
53
|
-
|
|
99
|
+
def search(jobset, substr)
|
|
100
|
+
resultset = jobset.scan(substr).to_a
|
|
101
|
+
@current_page = 1
|
|
102
|
+
@count = @total_size = resultset.size
|
|
103
|
+
resultset
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def filtering(which)
|
|
107
|
+
erb(:filtering, locals: {which: which})
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def filter_link(jid, within = "retries")
|
|
111
|
+
if within.nil?
|
|
112
|
+
::Rack::Utils.escape_html(jid)
|
|
113
|
+
else
|
|
114
|
+
"<a href='#{root_path}#{within}?substr=#{jid}'>#{::Rack::Utils.escape_html(jid)}</a>"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def display_tags(job, within = "retries")
|
|
119
|
+
job.tags.map { |tag|
|
|
120
|
+
"<span class='label label-info jobtag'>#{filter_link(tag, within)}</span>"
|
|
121
|
+
}.join(" ")
|
|
54
122
|
end
|
|
55
123
|
|
|
56
124
|
# This view helper provide ability display you html code in
|
|
@@ -96,7 +164,10 @@ module Sidekiq
|
|
|
96
164
|
#
|
|
97
165
|
# Inspiration taken from https://github.com/iain/http_accept_language/blob/master/lib/http_accept_language/parser.rb
|
|
98
166
|
def locale
|
|
99
|
-
|
|
167
|
+
# session[:locale] is set via the locale selector from the footer
|
|
168
|
+
@locale ||= if (l = session&.fetch(:locale, nil)) && available_locales.include?(l)
|
|
169
|
+
l
|
|
170
|
+
else
|
|
100
171
|
matched_locale = user_preferred_languages.map { |preferred|
|
|
101
172
|
preferred_language = preferred.split("-", 2).first
|
|
102
173
|
|
|
@@ -111,16 +182,10 @@ module Sidekiq
|
|
|
111
182
|
end
|
|
112
183
|
end
|
|
113
184
|
|
|
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
|
|
185
|
+
# sidekiq/sidekiq#3243
|
|
122
186
|
def unfiltered?
|
|
123
|
-
|
|
187
|
+
s = url_params("substr")
|
|
188
|
+
yield unless s && s.size > 0
|
|
124
189
|
end
|
|
125
190
|
|
|
126
191
|
def get_locale
|
|
@@ -137,7 +202,7 @@ module Sidekiq
|
|
|
137
202
|
end
|
|
138
203
|
|
|
139
204
|
def sort_direction_label
|
|
140
|
-
params[:direction] == "asc" ? "↑" : "↓"
|
|
205
|
+
(params[:direction] == "asc") ? "↑" : "↓"
|
|
141
206
|
end
|
|
142
207
|
|
|
143
208
|
def workset
|
|
@@ -161,22 +226,26 @@ module Sidekiq
|
|
|
161
226
|
end
|
|
162
227
|
end
|
|
163
228
|
|
|
229
|
+
def busy_weights(capsule_weights)
|
|
230
|
+
# backwards compat with 7.0.0, remove in 7.1
|
|
231
|
+
cw = [capsule_weights].flatten
|
|
232
|
+
cw.map { |hash|
|
|
233
|
+
hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
|
|
234
|
+
}.join("; ")
|
|
235
|
+
end
|
|
236
|
+
|
|
164
237
|
def stats
|
|
165
238
|
@stats ||= Sidekiq::Stats.new
|
|
166
239
|
end
|
|
167
240
|
|
|
168
|
-
def
|
|
241
|
+
def redis_url
|
|
169
242
|
Sidekiq.redis do |conn|
|
|
170
|
-
conn.
|
|
243
|
+
conn.config.server_url
|
|
171
244
|
end
|
|
172
245
|
end
|
|
173
246
|
|
|
174
|
-
def namespace
|
|
175
|
-
@ns ||= Sidekiq.redis { |conn| conn.respond_to?(:namespace) ? conn.namespace : nil }
|
|
176
|
-
end
|
|
177
|
-
|
|
178
247
|
def redis_info
|
|
179
|
-
Sidekiq.redis_info
|
|
248
|
+
Sidekiq.default_configuration.redis_info
|
|
180
249
|
end
|
|
181
250
|
|
|
182
251
|
def root_path
|
|
@@ -188,7 +257,7 @@ module Sidekiq
|
|
|
188
257
|
end
|
|
189
258
|
|
|
190
259
|
def current_status
|
|
191
|
-
workset.size == 0 ? "idle" : "active"
|
|
260
|
+
(workset.size == 0) ? "idle" : "active"
|
|
192
261
|
end
|
|
193
262
|
|
|
194
263
|
def relative_time(time)
|
|
@@ -221,7 +290,7 @@ module Sidekiq
|
|
|
221
290
|
end
|
|
222
291
|
|
|
223
292
|
def truncate(text, truncate_after_chars = 2000)
|
|
224
|
-
truncate_after_chars && text.size > truncate_after_chars ? "#{text[0..truncate_after_chars]}..." : text
|
|
293
|
+
(truncate_after_chars && text.size > truncate_after_chars) ? "#{text[0..truncate_after_chars]}..." : text
|
|
225
294
|
end
|
|
226
295
|
|
|
227
296
|
def display_args(args, truncate_after_chars = 2000)
|
|
@@ -241,6 +310,10 @@ module Sidekiq
|
|
|
241
310
|
"<input type='hidden' name='authenticity_token' value='#{env[:csrf_token]}'/>"
|
|
242
311
|
end
|
|
243
312
|
|
|
313
|
+
def csp_nonce
|
|
314
|
+
env[:csp_nonce]
|
|
315
|
+
end
|
|
316
|
+
|
|
244
317
|
def to_display(arg)
|
|
245
318
|
arg.inspect
|
|
246
319
|
rescue
|
|
@@ -274,27 +347,17 @@ module Sidekiq
|
|
|
274
347
|
elsif rss_kb < 10_000_000
|
|
275
348
|
"#{number_with_delimiter((rss_kb / 1024.0).to_i)} MB"
|
|
276
349
|
else
|
|
277
|
-
"#{number_with_delimiter(
|
|
350
|
+
"#{number_with_delimiter(rss_kb / (1024.0 * 1024.0), precision: 1)} GB"
|
|
278
351
|
end
|
|
279
352
|
end
|
|
280
353
|
|
|
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])
|
|
354
|
+
def number_with_delimiter(number, options = {})
|
|
355
|
+
precision = options[:precision] || 0
|
|
356
|
+
%(<span data-nwp="#{precision}">#{number.round(precision)}</span>)
|
|
294
357
|
end
|
|
295
358
|
|
|
296
359
|
def h(text)
|
|
297
|
-
::Rack::Utils.escape_html(text)
|
|
360
|
+
::Rack::Utils.escape_html(text.to_s)
|
|
298
361
|
rescue ArgumentError => e
|
|
299
362
|
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
|
300
363
|
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
|
@@ -314,7 +377,7 @@ module Sidekiq
|
|
|
314
377
|
end
|
|
315
378
|
|
|
316
379
|
def environment_title_prefix
|
|
317
|
-
environment = Sidekiq[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
|
380
|
+
environment = Sidekiq.default_configuration[:environment] || ENV["APP_ENV"] || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
|
318
381
|
|
|
319
382
|
"[#{environment.upcase}] " unless environment == "production"
|
|
320
383
|
end
|
|
@@ -327,11 +390,9 @@ module Sidekiq
|
|
|
327
390
|
Time.now.utc.strftime("%H:%M:%S UTC")
|
|
328
391
|
end
|
|
329
392
|
|
|
330
|
-
def
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
"#{redis_connection}#{namespace_suffix}"
|
|
334
|
-
end
|
|
393
|
+
def pollable?
|
|
394
|
+
# there's no point to refreshing the metrics pages every N seconds
|
|
395
|
+
!(current_path == "" || current_path.index("metrics"))
|
|
335
396
|
end
|
|
336
397
|
|
|
337
398
|
def retry_or_delete_or_kill(job, params)
|
data/lib/sidekiq/web/router.rb
CHANGED
|
@@ -39,10 +39,13 @@ module Sidekiq
|
|
|
39
39
|
route(DELETE, path, &block)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
def route(
|
|
42
|
+
def route(*methods, path, &block)
|
|
43
43
|
@routes ||= {GET => [], POST => [], PUT => [], PATCH => [], DELETE => [], HEAD => []}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
methods.each do |method|
|
|
46
|
+
method = method.to_s.upcase
|
|
47
|
+
@routes[method] << WebRoute.new(method, path, block)
|
|
48
|
+
end
|
|
46
49
|
end
|
|
47
50
|
|
|
48
51
|
def match(env)
|
data/lib/sidekiq/web.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "erb"
|
|
4
|
+
require "securerandom"
|
|
4
5
|
|
|
5
6
|
require "sidekiq"
|
|
6
7
|
require "sidekiq/api"
|
|
@@ -30,14 +31,30 @@ module Sidekiq
|
|
|
30
31
|
"Queues" => "queues",
|
|
31
32
|
"Retries" => "retries",
|
|
32
33
|
"Scheduled" => "scheduled",
|
|
33
|
-
"Dead" => "morgue"
|
|
34
|
+
"Dead" => "morgue",
|
|
35
|
+
"Metrics" => "metrics"
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
+
if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3")
|
|
39
|
+
CONTENT_LANGUAGE = "Content-Language"
|
|
40
|
+
CONTENT_SECURITY_POLICY = "Content-Security-Policy"
|
|
41
|
+
LOCATION = "Location"
|
|
42
|
+
X_CASCADE = "X-Cascade"
|
|
43
|
+
X_CONTENT_TYPE_OPTIONS = "X-Content-Type-Options"
|
|
44
|
+
else
|
|
45
|
+
CONTENT_LANGUAGE = "content-language"
|
|
46
|
+
CONTENT_SECURITY_POLICY = "content-security-policy"
|
|
47
|
+
LOCATION = "location"
|
|
48
|
+
X_CASCADE = "x-cascade"
|
|
49
|
+
X_CONTENT_TYPE_OPTIONS = "x-content-type-options"
|
|
38
50
|
end
|
|
39
51
|
|
|
40
52
|
class << self
|
|
53
|
+
# Forward compatibility with 8.0
|
|
54
|
+
def configure
|
|
55
|
+
yield self
|
|
56
|
+
end
|
|
57
|
+
|
|
41
58
|
def settings
|
|
42
59
|
self
|
|
43
60
|
end
|
|
@@ -51,6 +68,10 @@ module Sidekiq
|
|
|
51
68
|
end
|
|
52
69
|
alias_method :tabs, :custom_tabs
|
|
53
70
|
|
|
71
|
+
def custom_job_info_rows
|
|
72
|
+
@custom_job_info_rows ||= []
|
|
73
|
+
end
|
|
74
|
+
|
|
54
75
|
def locales
|
|
55
76
|
@locales ||= LOCALES
|
|
56
77
|
end
|
|
@@ -79,14 +100,6 @@ module Sidekiq
|
|
|
79
100
|
send(:"#{attribute}=", value)
|
|
80
101
|
end
|
|
81
102
|
|
|
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
103
|
attr_accessor :app_url, :redis_pool
|
|
91
104
|
attr_writer :locales, :views
|
|
92
105
|
end
|
|
@@ -109,6 +122,7 @@ module Sidekiq
|
|
|
109
122
|
end
|
|
110
123
|
|
|
111
124
|
def call(env)
|
|
125
|
+
env[:csp_nonce] = SecureRandom.base64(16)
|
|
112
126
|
app.call(env)
|
|
113
127
|
end
|
|
114
128
|
|
|
@@ -133,11 +147,50 @@ module Sidekiq
|
|
|
133
147
|
send(:"#{attribute}=", value)
|
|
134
148
|
end
|
|
135
149
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
150
|
+
# Register a class as a Sidekiq Web UI extension. The class should
|
|
151
|
+
# provide one or more tabs which map to an index route. Options:
|
|
152
|
+
#
|
|
153
|
+
# @param extension [Class] Class which contains the HTTP actions, required
|
|
154
|
+
# @param name [String] the name of the extension, used to namespace assets
|
|
155
|
+
# @param tab [String | Array] labels(s) of the UI tabs
|
|
156
|
+
# @param index [String | Array] index route(s) for each tab
|
|
157
|
+
# @param root_dir [String] directory location to find assets, locales and views, typically `web/` within the gemfile
|
|
158
|
+
# @param asset_paths [Array] one or more directories under {root}/assets/{name} to be publicly served, e.g. ["js", "css", "img"]
|
|
159
|
+
# @param cache_for [Integer] amount of time to cache assets, default one day
|
|
160
|
+
#
|
|
161
|
+
# TODO name, tab and index will be mandatory in 8.0
|
|
162
|
+
#
|
|
163
|
+
# Web extensions will have a root `web/` directory with `locales/`, `assets/`
|
|
164
|
+
# and `views/` subdirectories.
|
|
165
|
+
def self.register(extension, name: nil, tab: nil, index: nil, root_dir: nil, cache_for: 86400, asset_paths: nil)
|
|
166
|
+
tab = Array(tab)
|
|
167
|
+
index = Array(index)
|
|
168
|
+
tab.zip(index).each do |tab, index|
|
|
169
|
+
tabs[tab] = index
|
|
170
|
+
end
|
|
171
|
+
if root_dir
|
|
172
|
+
locdir = File.join(root_dir, "locales")
|
|
173
|
+
locales << locdir if File.directory?(locdir)
|
|
174
|
+
|
|
175
|
+
if asset_paths && name
|
|
176
|
+
# if you have {root}/assets/{name}/js/scripts.js
|
|
177
|
+
# and {root}/assets/{name}/css/styles.css
|
|
178
|
+
# you would pass in:
|
|
179
|
+
# asset_paths: ["js", "css"]
|
|
180
|
+
# See script_tag and style_tag in web/helpers.rb
|
|
181
|
+
assdir = File.join(root_dir, "assets")
|
|
182
|
+
assurls = Array(asset_paths).map { |x| "/#{name}/#{x}" }
|
|
183
|
+
assetprops = {
|
|
184
|
+
urls: assurls,
|
|
185
|
+
root: assdir,
|
|
186
|
+
cascade: true
|
|
187
|
+
}
|
|
188
|
+
assetprops[:header_rules] = [[:all, {Rack::CACHE_CONTROL => "private, max-age=#{cache_for.to_i}"}]] if cache_for
|
|
189
|
+
middlewares << [[Rack::Static, assetprops], nil]
|
|
190
|
+
end
|
|
191
|
+
end
|
|
139
192
|
|
|
140
|
-
|
|
193
|
+
yield self if block_given?
|
|
141
194
|
extension.registered(WebApplication)
|
|
142
195
|
end
|
|
143
196
|
|
|
@@ -148,7 +201,7 @@ module Sidekiq
|
|
|
148
201
|
m = middlewares
|
|
149
202
|
|
|
150
203
|
rules = []
|
|
151
|
-
rules = [[:all, {
|
|
204
|
+
rules = [[:all, {Rack::CACHE_CONTROL => "private, max-age=86400"}]] unless ENV["SIDEKIQ_WEB_TESTING"]
|
|
152
205
|
|
|
153
206
|
::Rack::Builder.new do
|
|
154
207
|
use Rack::Static, urls: ["/stylesheets", "/images", "/javascripts"],
|
|
@@ -165,7 +218,7 @@ module Sidekiq
|
|
|
165
218
|
Sidekiq::WebApplication.helpers WebHelpers
|
|
166
219
|
Sidekiq::WebApplication.helpers Sidekiq::Paginator
|
|
167
220
|
|
|
168
|
-
Sidekiq::WebAction.class_eval <<-RUBY,
|
|
221
|
+
Sidekiq::WebAction.class_eval <<-RUBY, Web::LAYOUT, -1 # standard:disable Style/EvalWithLocation
|
|
169
222
|
def _render
|
|
170
223
|
#{ERB.new(File.read(Web::LAYOUT)).src}
|
|
171
224
|
end
|
|
@@ -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
|