sidekiq 8.1.5 → 8.1.6
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 +10 -0
- data/lib/sidekiq/config.rb +3 -7
- data/lib/sidekiq/job.rb +1 -1
- data/lib/sidekiq/job_retry.rb +1 -1
- data/lib/sidekiq/manager.rb +1 -0
- data/lib/sidekiq/redis_client_adapter.rb +2 -2
- data/lib/sidekiq/testing.rb +1 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +2 -2
- data/lib/sidekiq/web/application.rb +11 -2
- data/lib/sidekiq/web/helpers.rb +9 -14
- data/lib/sidekiq/web/router.rb +2 -2
- data/web/views/busy.html.erb +49 -45
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e36b05d6e25f174a0ff8b8a21b4c097a108e4ccf98af88a56ae767cfea1186a
|
|
4
|
+
data.tar.gz: c58b4f89a1466bac6c9de05cf5ea2aee0152ac42184946b4d1646c6938b351a8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b8690078001bb93fc6e4fb8fe4d52091d89c317d8dcef56d24247882f4c85dbe986a05ae5451aaf70b9ff25c4acbc89b2d15e909763550bbcb13f36e73b2f7f
|
|
7
|
+
data.tar.gz: 3cabd5a3a2861af5faf70c5f67d8eb93c578d58cb7825dc063e350f30ef37dc3e2c51060a58dcf2fca9915df1bb7fcbfd00d81996ba651c29882c8432545b03a
|
data/Changes.md
CHANGED
|
@@ -2,9 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
[Sidekiq Changes](https://github.com/sidekiq/sidekiq/blob/main/Changes.md) | [Sidekiq Pro Changes](https://github.com/sidekiq/sidekiq/blob/main/Pro-Changes.md) | [Sidekiq Enterprise Changes](https://github.com/sidekiq/sidekiq/blob/main/Ent-Changes.md)
|
|
4
4
|
|
|
5
|
+
8.1.6
|
|
6
|
+
----------
|
|
7
|
+
|
|
8
|
+
- Fix reported thread/memory leak when jobs fail [#7006]
|
|
9
|
+
- Users can limit data displayed on Busy page with the `only` parameter `/busy?only=(jobs|processes)` [#6992]
|
|
10
|
+
- Replace Rack::Utils usage with standard library APIs
|
|
11
|
+
- Several minor fixes from AI scanners.
|
|
12
|
+
|
|
5
13
|
8.1.5
|
|
6
14
|
----------
|
|
7
15
|
|
|
16
|
+
- Fix sub-second precision when computing the `retry_for` deadline [#7003]
|
|
8
17
|
- Identify Sidekiq connnections in Redis with `CLIENT SETINFO` [#6986]
|
|
9
18
|
- Fix edge case where Web UI could show an empty Batch set [#6987]
|
|
10
19
|
|
|
@@ -47,6 +56,7 @@ Use REDIS_URL or REDIS_PROVIDER to point `kiq` to Redis.
|
|
|
47
56
|
require "sidekiq/testing"
|
|
48
57
|
require "sidekiq/testing/inline"
|
|
49
58
|
# New, more explicit
|
|
59
|
+
require "sidekiq"
|
|
50
60
|
Sidekiq.testing!(:fake)
|
|
51
61
|
Sidekiq.testing!(:inline)
|
|
52
62
|
```
|
data/lib/sidekiq/config.rb
CHANGED
|
@@ -297,15 +297,11 @@ module Sidekiq
|
|
|
297
297
|
@logger = logger
|
|
298
298
|
end
|
|
299
299
|
|
|
300
|
-
private def parameter_size(handler)
|
|
301
|
-
target = handler.is_a?(Proc) ? handler : handler.method(:call)
|
|
302
|
-
target.parameters.size
|
|
303
|
-
end
|
|
304
|
-
|
|
305
300
|
# INTERNAL USE ONLY
|
|
306
301
|
def handle_exception(ex, ctx = {})
|
|
307
|
-
if @options[:error_handlers].
|
|
308
|
-
|
|
302
|
+
if @options[:error_handlers].empty?
|
|
303
|
+
logger.error { "No error handlers configured, logging exception directly" }
|
|
304
|
+
logger.error { ex }
|
|
309
305
|
end
|
|
310
306
|
@options[:error_handlers].each do |handler|
|
|
311
307
|
handler.call(ex, ctx, self)
|
data/lib/sidekiq/job.rb
CHANGED
|
@@ -196,7 +196,7 @@ module Sidekiq
|
|
|
196
196
|
|
|
197
197
|
def set(options)
|
|
198
198
|
hash = options.transform_keys(&:to_s)
|
|
199
|
-
interval = hash.delete("wait_until") ||
|
|
199
|
+
interval = hash.delete("wait_until") || hash.delete("wait")
|
|
200
200
|
@opts.merge!(hash)
|
|
201
201
|
at(interval) if interval
|
|
202
202
|
self
|
data/lib/sidekiq/job_retry.rb
CHANGED
data/lib/sidekiq/manager.rb
CHANGED
|
@@ -41,8 +41,8 @@ module Sidekiq
|
|
|
41
41
|
# this allows us to use methods like `conn.hmset(...)` instead of having to use
|
|
42
42
|
# redis-client's native `conn.call("hmset", ...)`
|
|
43
43
|
def method_missing(*args, &block)
|
|
44
|
-
warn("[sidekiq#5788] Redis has deprecated the `#{args.first}`command, called at #{caller(1..1)}") if DEPRECATED_COMMANDS.include?(args.first)
|
|
45
|
-
@client.call(*args,
|
|
44
|
+
warn("[sidekiq#5788] Redis has deprecated the `#{args.first}` command, called at #{caller(1..1)}") if DEPRECATED_COMMANDS.include?(args.first)
|
|
45
|
+
@client.call(*args, &block)
|
|
46
46
|
end
|
|
47
47
|
ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
|
|
48
48
|
|
data/lib/sidekiq/testing.rb
CHANGED
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
|
@@ -24,8 +24,8 @@ module Sidekiq
|
|
|
24
24
|
@request ||= ::Rack::Request.new(env)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def halt(res)
|
|
28
|
-
throw :halt, [res, {"content-type" => "text/plain"}, [res.to_s]]
|
|
27
|
+
def halt(res, msg = nil)
|
|
28
|
+
throw :halt, [res, {"content-type" => "text/plain"}, [msg || res.to_s]]
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# external redirect
|
|
@@ -90,9 +90,18 @@ module Sidekiq
|
|
|
90
90
|
|
|
91
91
|
get "/busy" do
|
|
92
92
|
@count = (url_params("count") || 100).to_i
|
|
93
|
-
(@current_page, @total_size, @workset) = page_items(workset, url_params("page"), @count)
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
# Use /busy?only=(jobs|processes) to limit page data
|
|
95
|
+
only = url_params("only")
|
|
96
|
+
halt 401, "Invalid value for only" unless only.nil? || only == "jobs" || only == "processes"
|
|
97
|
+
|
|
98
|
+
@show_jobs = (only != "processes")
|
|
99
|
+
@show_processes = (only != "jobs")
|
|
100
|
+
|
|
101
|
+
if @show_jobs
|
|
102
|
+
(@current_page, @total_size, @workset) = page_items(workset, url_params("page"), @count)
|
|
103
|
+
@iterable_states = Sidekiq::IterableJobQuery.new(workset.map { |_, _, work| work.job.jid })
|
|
104
|
+
end
|
|
96
105
|
|
|
97
106
|
erb(:busy)
|
|
98
107
|
end
|
data/lib/sidekiq/web/helpers.rb
CHANGED
|
@@ -72,19 +72,13 @@ module Sidekiq
|
|
|
72
72
|
# so extensions can be localized
|
|
73
73
|
@@strings[lang] ||= config.locales.each_with_object({}) do |path, global|
|
|
74
74
|
find_locale_files(lang).each do |file|
|
|
75
|
-
strs =
|
|
75
|
+
strs = parse_yaml(file)
|
|
76
76
|
global.merge!(strs[lang])
|
|
77
77
|
end
|
|
78
78
|
end
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
def parse_yaml_old(path)
|
|
83
|
-
require "yaml"
|
|
84
|
-
YAML.safe_load_file(path)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def parse_yaml_new(path)
|
|
81
|
+
def parse_yaml(path)
|
|
88
82
|
locale = nil
|
|
89
83
|
map = {}
|
|
90
84
|
IO.readlines(path, chomp: true).each do |line|
|
|
@@ -156,17 +150,18 @@ module Sidekiq
|
|
|
156
150
|
erb(:filtering, locals: {which:, placeholder_key:, label_key:})
|
|
157
151
|
end
|
|
158
152
|
|
|
159
|
-
def filter_link(
|
|
153
|
+
def filter_link(str, within = "retries")
|
|
154
|
+
hstr = h(str)
|
|
160
155
|
if within.nil?
|
|
161
|
-
|
|
156
|
+
hstr
|
|
162
157
|
else
|
|
163
|
-
"<a href='#{root_path}#{within}?substr=#{
|
|
158
|
+
"<a href='#{root_path}#{within}?substr=#{hstr}'>#{hstr}</a>"
|
|
164
159
|
end
|
|
165
160
|
end
|
|
166
161
|
|
|
167
162
|
def display_tags(job, within = "retries")
|
|
168
163
|
job.tags.map { |tag|
|
|
169
|
-
"<span class='label label-info jobtag jobtag-#{
|
|
164
|
+
"<span class='label label-info jobtag jobtag-#{h(tag)}'>#{filter_link(tag, within)}</span>"
|
|
170
165
|
}.join(" ")
|
|
171
166
|
end
|
|
172
167
|
|
|
@@ -337,7 +332,7 @@ module Sidekiq
|
|
|
337
332
|
[score.to_f, jid]
|
|
338
333
|
end
|
|
339
334
|
|
|
340
|
-
SAFE_QPARAMS = %w[page direction]
|
|
335
|
+
SAFE_QPARAMS = %w[page direction only]
|
|
341
336
|
|
|
342
337
|
# Merge options with current params, filter safe params, and stringify to query string
|
|
343
338
|
def qparams(options)
|
|
@@ -420,7 +415,7 @@ module Sidekiq
|
|
|
420
415
|
end
|
|
421
416
|
|
|
422
417
|
def h(text)
|
|
423
|
-
::
|
|
418
|
+
::CGI.escapeHTML(text.to_s)
|
|
424
419
|
rescue ArgumentError => e
|
|
425
420
|
raise unless e.message.eql?("invalid byte sequence in UTF-8")
|
|
426
421
|
text.encode!("UTF-16", "UTF-8", invalid: :replace, replace: "").encode!("UTF-8", "UTF-16")
|
data/lib/sidekiq/web/router.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "uri"
|
|
4
4
|
|
|
5
5
|
module Sidekiq
|
|
6
6
|
class Web
|
|
@@ -28,7 +28,7 @@ module Sidekiq
|
|
|
28
28
|
|
|
29
29
|
def match(env)
|
|
30
30
|
request_method = env["REQUEST_METHOD"].downcase.to_sym
|
|
31
|
-
path_info = ::
|
|
31
|
+
path_info = ::URI::RFC2396_PARSER.unescape env["PATH_INFO"]
|
|
32
32
|
|
|
33
33
|
# There are servers which send an empty string when requesting the root.
|
|
34
34
|
# These servers should be ashamed of themselves.
|
data/web/views/busy.html.erb
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
</section>
|
|
29
29
|
|
|
30
|
+
<% if @show_processes %>
|
|
30
31
|
<section>
|
|
31
32
|
<header>
|
|
32
33
|
<h2><%= t('Processes') %></h2>
|
|
@@ -102,50 +103,53 @@
|
|
|
102
103
|
</table>
|
|
103
104
|
</div>
|
|
104
105
|
</section>
|
|
106
|
+
<% end %>
|
|
105
107
|
|
|
106
|
-
|
|
107
|
-
<
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
</header>
|
|
113
|
-
|
|
114
|
-
<div class="table_container">
|
|
115
|
-
<table>
|
|
116
|
-
<thead>
|
|
117
|
-
<th><%= t('Process') %></th>
|
|
118
|
-
<th><%= t('TID') %></th>
|
|
119
|
-
<th><%= t('JID') %></th>
|
|
120
|
-
<th><%= t('Queue') %></th>
|
|
121
|
-
<th><%= t('Job') %></th>
|
|
122
|
-
<th><%= t('Arguments') %></th>
|
|
123
|
-
<th><%= t('Started') %></th>
|
|
124
|
-
</thead>
|
|
125
|
-
<% @workset.each do |process, thread, work| %>
|
|
126
|
-
<% job = work.job %>
|
|
127
|
-
<tr>
|
|
128
|
-
<td><%= process %></td>
|
|
129
|
-
<td><%= thread %></td>
|
|
130
|
-
<td><%= job.jid %></td>
|
|
131
|
-
<td>
|
|
132
|
-
<a href="<%= root_path %>queues/<%= work.queue %>"><%= work.queue %></a>
|
|
133
|
-
</td>
|
|
134
|
-
<td>
|
|
135
|
-
<%= job.display_class %>
|
|
136
|
-
<%= display_tags(job, nil) %>
|
|
137
|
-
</td>
|
|
138
|
-
<td>
|
|
139
|
-
<code><div class="args"><%= display_args(job.display_args) %></div></code>
|
|
140
|
-
</td>
|
|
141
|
-
<td>
|
|
142
|
-
<%= relative_time(work.run_at) %>
|
|
143
|
-
<% if (state = @iterable_states[job.jid]) %>
|
|
144
|
-
<div><small>cursor=<%= h(truncate(state.cursor.inspect, 100)) %>; exec=<%= state.executions %>; rt=<%= number_with_delimiter(state.runtime, precision: 3) %>s</small></div>
|
|
145
|
-
<% end %>
|
|
146
|
-
</td>
|
|
147
|
-
</tr>
|
|
108
|
+
<% if @show_jobs %>
|
|
109
|
+
<section>
|
|
110
|
+
<header>
|
|
111
|
+
<h2><%= t('Jobs') %></h2>
|
|
112
|
+
<% if @workset.size > 0 && @total_size > @count %>
|
|
113
|
+
<%= erb :_paging, locals: { url: "#{root_path}busy" } %>
|
|
148
114
|
<% end %>
|
|
149
|
-
</
|
|
150
|
-
|
|
151
|
-
|
|
115
|
+
</header>
|
|
116
|
+
|
|
117
|
+
<div class="table_container">
|
|
118
|
+
<table>
|
|
119
|
+
<thead>
|
|
120
|
+
<th><%= t('Process') %></th>
|
|
121
|
+
<th><%= t('TID') %></th>
|
|
122
|
+
<th><%= t('JID') %></th>
|
|
123
|
+
<th><%= t('Queue') %></th>
|
|
124
|
+
<th><%= t('Job') %></th>
|
|
125
|
+
<th><%= t('Arguments') %></th>
|
|
126
|
+
<th><%= t('Started') %></th>
|
|
127
|
+
</thead>
|
|
128
|
+
<% @workset.each do |process, thread, work| %>
|
|
129
|
+
<% job = work.job %>
|
|
130
|
+
<tr>
|
|
131
|
+
<td><%= process %></td>
|
|
132
|
+
<td><%= thread %></td>
|
|
133
|
+
<td><%= job.jid %></td>
|
|
134
|
+
<td>
|
|
135
|
+
<a href="<%= root_path %>queues/<%= work.queue %>"><%= work.queue %></a>
|
|
136
|
+
</td>
|
|
137
|
+
<td>
|
|
138
|
+
<%= job.display_class %>
|
|
139
|
+
<%= display_tags(job, nil) %>
|
|
140
|
+
</td>
|
|
141
|
+
<td>
|
|
142
|
+
<code><div class="args"><%= display_args(job.display_args) %></div></code>
|
|
143
|
+
</td>
|
|
144
|
+
<td>
|
|
145
|
+
<%= relative_time(work.run_at) %>
|
|
146
|
+
<% if (state = @iterable_states[job.jid]) %>
|
|
147
|
+
<div><small>cursor=<%= h(truncate(state.cursor.inspect, 100)) %>; exec=<%= state.executions %>; rt=<%= number_with_delimiter(state.runtime, precision: 3) %>s</small></div>
|
|
148
|
+
<% end %>
|
|
149
|
+
</td>
|
|
150
|
+
</tr>
|
|
151
|
+
<% end %>
|
|
152
|
+
</table>
|
|
153
|
+
</div>
|
|
154
|
+
</section>
|
|
155
|
+
<% end %>
|