sidekiq 8.0.8 → 8.1.0
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 +42 -0
- data/README.md +15 -0
- data/bin/lint-herb +13 -0
- data/lib/generators/sidekiq/templates/job.rb.erb +1 -1
- data/lib/sidekiq/api.rb +28 -5
- data/lib/sidekiq/capsule.rb +4 -0
- data/lib/sidekiq/cli.rb +16 -4
- data/lib/sidekiq/config.rb +8 -2
- data/lib/sidekiq/fetch.rb +1 -0
- data/lib/sidekiq/job/iterable.rb +2 -2
- data/lib/sidekiq/job.rb +2 -0
- data/lib/sidekiq/job_logger.rb +4 -2
- data/lib/sidekiq/job_retry.rb +7 -3
- data/lib/sidekiq/launcher.rb +18 -9
- data/lib/sidekiq/middleware/i18n.rb +2 -0
- data/lib/sidekiq/monitor.rb +4 -8
- data/lib/sidekiq/profiler.rb +1 -0
- data/lib/sidekiq/redis_connection.rb +2 -2
- data/lib/sidekiq/ring_buffer.rb +1 -0
- data/lib/sidekiq/scheduled.rb +7 -5
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +1 -1
- data/lib/sidekiq/web/application.rb +10 -0
- data/lib/sidekiq/web/config.rb +3 -6
- data/lib/sidekiq/web/helpers.rb +3 -11
- data/lib/sidekiq/web.rb +23 -4
- data/sidekiq.gemspec +5 -5
- data/web/assets/javascripts/application.js +17 -1
- data/web/assets/stylesheets/style.css +17 -2
- data/web/locales/ar.yml +1 -0
- data/web/locales/cs.yml +1 -0
- data/web/locales/da.yml +1 -0
- data/web/locales/de.yml +1 -0
- data/web/locales/el.yml +1 -0
- data/web/locales/en.yml +1 -0
- data/web/locales/es.yml +1 -0
- data/web/locales/fa.yml +1 -0
- data/web/locales/fr.yml +2 -1
- data/web/locales/gd.yml +1 -0
- data/web/locales/he.yml +1 -0
- data/web/locales/hi.yml +1 -0
- data/web/locales/it.yml +1 -0
- data/web/locales/ja.yml +1 -0
- data/web/locales/ko.yml +1 -0
- data/web/locales/lt.yml +1 -0
- data/web/locales/nb.yml +1 -0
- data/web/locales/nl.yml +1 -0
- data/web/locales/pl.yml +1 -0
- data/web/locales/pt-BR.yml +1 -0
- data/web/locales/pt.yml +1 -0
- data/web/locales/ru.yml +1 -0
- data/web/locales/sv.yml +1 -0
- data/web/locales/ta.yml +1 -0
- data/web/locales/tr.yml +1 -0
- data/web/locales/uk.yml +1 -0
- data/web/locales/ur.yml +1 -0
- data/web/locales/vi.yml +1 -0
- data/web/locales/zh-CN.yml +1 -0
- data/web/locales/zh-TW.yml +1 -0
- data/web/views/{_footer.erb → _footer.html.erb} +1 -1
- data/web/views/{_metrics_period_select.erb → _metrics_period_select.html.erb} +1 -1
- data/web/views/{_paging.erb → _paging.html.erb} +0 -1
- data/web/views/_poll_link.html.erb +4 -0
- data/web/views/{busy.erb → busy.html.erb} +4 -8
- data/web/views/{dashboard.erb → dashboard.html.erb} +3 -3
- data/web/views/{dead.erb → dead.html.erb} +3 -3
- data/web/views/filtering.html.erb +6 -0
- data/web/views/{layout.erb → layout.html.erb} +7 -7
- data/web/views/{metrics.erb → metrics.html.erb} +9 -8
- data/web/views/{morgue.erb → morgue.html.erb} +8 -4
- data/web/views/{queue.erb → queue.html.erb} +2 -2
- data/web/views/{queues.erb → queues.html.erb} +4 -4
- data/web/views/{retries.erb → retries.html.erb} +9 -5
- data/web/views/{retry.erb → retry.html.erb} +2 -2
- data/web/views/{scheduled.erb → scheduled.html.erb} +8 -4
- data/web/views/{scheduled_job_info.erb → scheduled_job_info.html.erb} +2 -2
- metadata +34 -34
- data/lib/sidekiq/web/csrf_protection.rb +0 -183
- data/web/views/_poll_link.erb +0 -4
- data/web/views/filtering.erb +0 -6
- /data/web/views/{_job_info.erb → _job_info.html.erb} +0 -0
- /data/web/views/{_nav.erb → _nav.html.erb} +0 -0
- /data/web/views/{_summary.erb → _summary.html.erb} +0 -0
- /data/web/views/{metrics_for_job.erb → metrics_for_job.html.erb} +0 -0
- /data/web/views/{profiles.erb → profiles.html.erb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 63658318932ac6b7045211590b07f84ed9e1e6398f908ace790a0df20d5ac1f0
|
|
4
|
+
data.tar.gz: 0c3f5e69ada7529bdac7392acb1c56ef2a19b8ed13210be8c36aac19858c6df4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9a5e95a2faccbbf42f8e651c4882c9495ad72b0500bb8fe77fa2a93fb4aa6f8cb96fc820621cd1910fb4b00accf35d75a99d548b3cc8ccdd41a18b5620a9ad73
|
|
7
|
+
data.tar.gz: 1bc66490ee07c548c71f680fb280e876efa7eeb8c6f234277df73211ce05c5ae29f5c9bc13064972da945568d1df6634252a6c22a7c5298bdd436b7266246c53
|
data/Changes.md
CHANGED
|
@@ -2,6 +2,48 @@
|
|
|
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.0
|
|
6
|
+
----------
|
|
7
|
+
|
|
8
|
+
- `retry_for` and `retry` are now mutually exclusive [#6878, Saidbek]
|
|
9
|
+
- `perform_inline` now enforces `strict_args!` [#6718, Saidbek]
|
|
10
|
+
- Integrate Herb linting for ERB templates [#6760, Saidbek]
|
|
11
|
+
- Remove CSRF code, use `Sec-Fetch-Site` header [#6874, deve1212]
|
|
12
|
+
- Allow custom Web UI `assets_path` for CDN purposes [#6865, stanhu]
|
|
13
|
+
- Upgrade to connection_pool 3.0
|
|
14
|
+
- Allow idle connection reaping after N seconds.
|
|
15
|
+
You can activate this **beta** feature like below.
|
|
16
|
+
Feedback requested: is this feature stable and useful for you in production?
|
|
17
|
+
This feature may or may not be enabled by default in Sidekiq 9.0.
|
|
18
|
+
```ruby
|
|
19
|
+
Sidekiq.configure_server do |cfg|
|
|
20
|
+
cfg.reap_idle_redis_connections(60)
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
8.0.10
|
|
25
|
+
----------
|
|
26
|
+
|
|
27
|
+
- Add confirm dialog for Delete All buttons in Web UI [#6853]
|
|
28
|
+
- Adjust scheduler to run closer to poll average [#6866]
|
|
29
|
+
- Forward compatibility changes for connection_pool 3.0.0
|
|
30
|
+
- Backwards compatibility fix for <8.0.9 process data in Redis [#6870]
|
|
31
|
+
- Backtrace dump can now be triggered with the INFO signal, since Puma uses the
|
|
32
|
+
same signal [#6857]
|
|
33
|
+
|
|
34
|
+
8.0.9
|
|
35
|
+
----------
|
|
36
|
+
|
|
37
|
+
- Implement idle Redis connection reaping, will be activated in 8.1 [#6663]
|
|
38
|
+
- Updated `Sidekiq::Process` API to provide capsule data. The `queues` and `weights`
|
|
39
|
+
data will be removed from Redis in Sidekiq 8.1, as this data can now be found in the
|
|
40
|
+
`capsules` element. [#6295]
|
|
41
|
+
- Restore bulk action buttons on Scheduled, Retry and Dead tabs [#6833, deve1212]
|
|
42
|
+
- Support logging additional job attributes [#6846, bschrag620]
|
|
43
|
+
- Fix display of long job args [#6836]
|
|
44
|
+
- Create development lifecycle (`docs/sdlc.md`) and security (`docs/SECURITY.md`) policy
|
|
45
|
+
documentation for Sidekiq's current workflows
|
|
46
|
+
|
|
5
47
|
8.0.8
|
|
6
48
|
----------
|
|
7
49
|
|
data/README.md
CHANGED
|
@@ -97,6 +97,21 @@ Contributing
|
|
|
97
97
|
|
|
98
98
|
See [the contributing guidelines](https://github.com/sidekiq/sidekiq/blob/main/.github/contributing.md).
|
|
99
99
|
|
|
100
|
+
### ERB Linting with HERB
|
|
101
|
+
|
|
102
|
+
This project uses [HERB](https://herb-tools.dev/) for ERB file linting and formatting. All ERB files have been renamed to use the `.html.erb` extension for better tooling support.
|
|
103
|
+
|
|
104
|
+
**Local Development:**
|
|
105
|
+
```bash
|
|
106
|
+
# Run HERB linting
|
|
107
|
+
bundle exec rake lint:herb
|
|
108
|
+
# or
|
|
109
|
+
bin/lint-herb
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**CI Integration:**
|
|
113
|
+
HERB linting is automatically run in CI to ensure all ERB files are properly formatted and free of parse errors.
|
|
114
|
+
|
|
100
115
|
License
|
|
101
116
|
-----------------
|
|
102
117
|
|
data/bin/lint-herb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# HERB Linting Script
|
|
5
|
+
# Run this script to lint all ERB files in the project
|
|
6
|
+
# Usage: bin/lint-herb
|
|
7
|
+
|
|
8
|
+
require "bundler/setup"
|
|
9
|
+
|
|
10
|
+
puts "🔍 Running HERB linting on ERB files..."
|
|
11
|
+
puts
|
|
12
|
+
|
|
13
|
+
exec("bundle exec herb analyze web/views -n --no-log-file")
|
data/lib/sidekiq/api.rb
CHANGED
|
@@ -1059,9 +1059,9 @@ module Sidekiq
|
|
|
1059
1059
|
# 'started_at' => <process start time>,
|
|
1060
1060
|
# 'pid' => 12345,
|
|
1061
1061
|
# 'tag' => 'myapp'
|
|
1062
|
-
# 'concurrency' =>
|
|
1063
|
-
# '
|
|
1064
|
-
# 'busy' =>
|
|
1062
|
+
# 'concurrency' => 5,
|
|
1063
|
+
# 'capsules' => {"default" => {"mode" => "weighted", "concurrency" => 5, "weights" => {"default" => 2, "low" => 1}}},
|
|
1064
|
+
# 'busy' => 3,
|
|
1065
1065
|
# 'beat' => <last heartbeat>,
|
|
1066
1066
|
# 'identity' => <unique string identifying the process>,
|
|
1067
1067
|
# 'embedded' => true,
|
|
@@ -1089,12 +1089,35 @@ module Sidekiq
|
|
|
1089
1089
|
self["identity"]
|
|
1090
1090
|
end
|
|
1091
1091
|
|
|
1092
|
+
# deprecated, use capsules below
|
|
1092
1093
|
def queues
|
|
1093
|
-
|
|
1094
|
+
# Backwards compatibility with <8.0.8
|
|
1095
|
+
if !self["capsules"]
|
|
1096
|
+
self["queues"]
|
|
1097
|
+
else
|
|
1098
|
+
capsules.values.flat_map { |x| x["weights"].keys }.uniq
|
|
1099
|
+
end
|
|
1094
1100
|
end
|
|
1095
1101
|
|
|
1102
|
+
# deprecated, use capsules below
|
|
1096
1103
|
def weights
|
|
1097
|
-
|
|
1104
|
+
# Backwards compatibility with <8.0.8
|
|
1105
|
+
if !self["capsules"]
|
|
1106
|
+
self["weights"]
|
|
1107
|
+
else
|
|
1108
|
+
hash = {}
|
|
1109
|
+
capsules.values.each do |cap|
|
|
1110
|
+
# Note: will lose data if two capsules are processing the same named queue
|
|
1111
|
+
cap["weights"].each_pair do |queue, weight|
|
|
1112
|
+
hash[queue] = weight
|
|
1113
|
+
end
|
|
1114
|
+
end
|
|
1115
|
+
hash
|
|
1116
|
+
end
|
|
1117
|
+
end
|
|
1118
|
+
|
|
1119
|
+
def capsules
|
|
1120
|
+
self["capsules"]
|
|
1098
1121
|
end
|
|
1099
1122
|
|
|
1100
1123
|
def version
|
data/lib/sidekiq/capsule.rb
CHANGED
data/lib/sidekiq/cli.rb
CHANGED
|
@@ -49,7 +49,7 @@ module Sidekiq # :nodoc:
|
|
|
49
49
|
logger.info "Booted Rails #{::Rails.version} application in #{environment} environment" if rails_app?
|
|
50
50
|
|
|
51
51
|
self_read, self_write = IO.pipe
|
|
52
|
-
sigs = %w[INT TERM TTIN TSTP]
|
|
52
|
+
sigs = %w[INT TERM INFO TTIN TSTP]
|
|
53
53
|
# USR1 and USR2 don't work on the JVM
|
|
54
54
|
sigs << "USR2" if Sidekiq.pro? && !jruby?
|
|
55
55
|
sigs.each do |sig|
|
|
@@ -201,7 +201,19 @@ module Sidekiq # :nodoc:
|
|
|
201
201
|
cli.logger.info "Received TSTP, no longer accepting new work"
|
|
202
202
|
cli.launcher.quiet
|
|
203
203
|
},
|
|
204
|
+
# deprecated, use INFO
|
|
204
205
|
"TTIN" => ->(cli) {
|
|
206
|
+
cli.logger.error { "DEPRECATED: Please use the INFO signal for backtraces, support for TTIN will be removed in Sidekiq 9.0." }
|
|
207
|
+
Thread.list.each do |thread|
|
|
208
|
+
cli.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
|
|
209
|
+
if thread.backtrace
|
|
210
|
+
cli.logger.warn thread.backtrace.join("\n")
|
|
211
|
+
else
|
|
212
|
+
cli.logger.warn "<no backtrace available>"
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
},
|
|
216
|
+
"INFO" => ->(cli) {
|
|
205
217
|
Thread.list.each do |thread|
|
|
206
218
|
cli.logger.warn "Thread TID-#{(thread.object_id ^ ::Process.pid).to_s(36)} #{thread.name}"
|
|
207
219
|
if thread.backtrace
|
|
@@ -212,12 +224,12 @@ module Sidekiq # :nodoc:
|
|
|
212
224
|
end
|
|
213
225
|
}
|
|
214
226
|
}
|
|
215
|
-
UNHANDLED_SIGNAL_HANDLER = ->(cli) { cli.logger.info "No signal handler registered, ignoring" }
|
|
216
|
-
SIGNAL_HANDLERS.default = UNHANDLED_SIGNAL_HANDLER
|
|
217
227
|
|
|
218
228
|
def handle_signal(sig)
|
|
219
229
|
logger.debug "Got #{sig} signal"
|
|
220
|
-
SIGNAL_HANDLERS[sig]
|
|
230
|
+
hndlr = SIGNAL_HANDLERS[sig]
|
|
231
|
+
hndlr ? hndlr.call(self) :
|
|
232
|
+
logger.warn("No #{sig} signal handler registered, ignoring")
|
|
221
233
|
end
|
|
222
234
|
|
|
223
235
|
private
|
data/lib/sidekiq/config.rb
CHANGED
|
@@ -35,7 +35,9 @@ module Sidekiq
|
|
|
35
35
|
dead_max_jobs: 10_000,
|
|
36
36
|
dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
|
|
37
37
|
reloader: proc { |&block| block.call },
|
|
38
|
-
backtrace_cleaner: ->(backtrace) { backtrace }
|
|
38
|
+
backtrace_cleaner: ->(backtrace) { backtrace },
|
|
39
|
+
logged_job_attributes: ["bid", "tags"],
|
|
40
|
+
redis_idle_timeout: nil
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
ERROR_HANDLER = ->(ex, ctx, cfg = Sidekiq.default_configuration) {
|
|
@@ -144,11 +146,15 @@ module Sidekiq
|
|
|
144
146
|
@redis_config = @redis_config.merge(hash)
|
|
145
147
|
end
|
|
146
148
|
|
|
149
|
+
def reap_idle_redis_connections(timeout = 60)
|
|
150
|
+
self[:redis_idle_timeout] = timeout
|
|
151
|
+
end
|
|
152
|
+
|
|
147
153
|
def redis_pool
|
|
148
154
|
Thread.current[:sidekiq_redis_pool] || Thread.current[:sidekiq_capsule]&.redis_pool || local_redis_pool
|
|
149
155
|
end
|
|
150
156
|
|
|
151
|
-
|
|
157
|
+
def local_redis_pool
|
|
152
158
|
# this is our internal client/housekeeping pool. each capsule has its
|
|
153
159
|
# own pool for executing threads.
|
|
154
160
|
@redis ||= new_redis_pool(10, "internal")
|
data/lib/sidekiq/fetch.rb
CHANGED
data/lib/sidekiq/job/iterable.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Sidekiq
|
|
|
55
55
|
def cancel!
|
|
56
56
|
return @_cancelled if cancelled?
|
|
57
57
|
|
|
58
|
-
key =
|
|
58
|
+
key = iteration_key
|
|
59
59
|
_, result, _ = Sidekiq.redis do |c|
|
|
60
60
|
c.pipelined do |p|
|
|
61
61
|
p.hsetnx(key, "cancelled", Time.now.to_i)
|
|
@@ -177,7 +177,7 @@ module Sidekiq
|
|
|
177
177
|
private
|
|
178
178
|
|
|
179
179
|
def is_cancelled?
|
|
180
|
-
@_cancelled = Sidekiq.redis { |c| c.hget(
|
|
180
|
+
@_cancelled = Sidekiq.redis { |c| c.hget(iteration_key, "cancelled") }
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def fetch_previous_iteration_state
|
data/lib/sidekiq/job.rb
CHANGED
data/lib/sidekiq/job_logger.rb
CHANGED
|
@@ -29,8 +29,10 @@ module Sidekiq
|
|
|
29
29
|
jid: job_hash["jid"],
|
|
30
30
|
class: job_hash["wrapped"] || job_hash["class"]
|
|
31
31
|
}
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
@config[:logged_job_attributes].each do |attr|
|
|
34
|
+
h[attr.to_sym] = job_hash[attr] if job_hash.has_key?(attr)
|
|
35
|
+
end
|
|
34
36
|
|
|
35
37
|
Thread.current[:sidekiq_context] = h
|
|
36
38
|
level = job_hash["log_level"]
|
data/lib/sidekiq/job_retry.rb
CHANGED
|
@@ -178,10 +178,14 @@ module Sidekiq
|
|
|
178
178
|
msg["error_backtrace"] = compress_backtrace(lines)
|
|
179
179
|
end
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
# retry_for and retry are mutually exclusive - if retry_for is set,
|
|
182
|
+
# we exclusively use duration-based retry logic and ignore count-based logic
|
|
183
183
|
rf = msg["retry_for"]
|
|
184
|
-
|
|
184
|
+
if rf
|
|
185
|
+
return retries_exhausted(jobinst, msg, exception) if (time_for(msg["failed_at"]) + rf) < Time.now
|
|
186
|
+
elsif count >= max_retry_attempts
|
|
187
|
+
return retries_exhausted(jobinst, msg, exception)
|
|
188
|
+
end
|
|
185
189
|
|
|
186
190
|
strategy, delay = delay_for(jobinst, count, exception, msg)
|
|
187
191
|
case strategy
|
data/lib/sidekiq/launcher.rb
CHANGED
|
@@ -142,6 +142,12 @@ module Sidekiq
|
|
|
142
142
|
key = identity
|
|
143
143
|
fails = procd = 0
|
|
144
144
|
|
|
145
|
+
idle_timeout = config[:redis_idle_timeout]
|
|
146
|
+
if idle_timeout
|
|
147
|
+
config.capsules.each_value { |cap| cap.local_redis_pool.reap(idle_seconds: idle_timeout, &:close) }
|
|
148
|
+
config.local_redis_pool.reap(idle_seconds: idle_timeout, &:close)
|
|
149
|
+
end
|
|
150
|
+
|
|
145
151
|
begin
|
|
146
152
|
flush_stats
|
|
147
153
|
|
|
@@ -214,11 +220,11 @@ module Sidekiq
|
|
|
214
220
|
# Log a warning if it's a disaster.
|
|
215
221
|
if RTT_READINGS.all? { |x| x > RTT_WARNING_LEVEL }
|
|
216
222
|
logger.warn <<~EOM
|
|
217
|
-
Your Redis network connection
|
|
223
|
+
Your Redis network connection appears to be performing poorly.
|
|
218
224
|
Last RTT readings were #{RTT_READINGS.buffer.inspect}, ideally these should be < 1000.
|
|
219
|
-
Ensure Redis is running in the same AZ or datacenter as Sidekiq
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
Ensure Redis is running in the same AZ or datacenter as Sidekiq and that
|
|
226
|
+
your Sidekiq process is not CPU-saturated; reduce your concurrency and/or
|
|
227
|
+
see https://github.com/sidekiq/sidekiq/discussions/5039
|
|
222
228
|
EOM
|
|
223
229
|
RTT_READINGS.reset
|
|
224
230
|
end
|
|
@@ -252,8 +258,15 @@ module Sidekiq
|
|
|
252
258
|
"pid" => ::Process.pid,
|
|
253
259
|
"tag" => @config[:tag] || "",
|
|
254
260
|
"concurrency" => @config.total_concurrency,
|
|
261
|
+
"capsules" => @config.capsules.each_with_object({}) { |(name, cap), memo|
|
|
262
|
+
memo[name] = cap.to_h
|
|
263
|
+
},
|
|
264
|
+
#####
|
|
265
|
+
# TODO deprecated, remove in 9.0
|
|
266
|
+
# This data is now found in the `capsules` element above
|
|
255
267
|
"queues" => @config.capsules.values.flat_map { |cap| cap.queues }.uniq,
|
|
256
|
-
"weights" =>
|
|
268
|
+
"weights" => @config.capsules.values.map(&:weights),
|
|
269
|
+
#####
|
|
257
270
|
"labels" => @config[:labels].to_a,
|
|
258
271
|
"identity" => identity,
|
|
259
272
|
"version" => Sidekiq::VERSION,
|
|
@@ -261,10 +274,6 @@ module Sidekiq
|
|
|
261
274
|
}
|
|
262
275
|
end
|
|
263
276
|
|
|
264
|
-
def to_weights
|
|
265
|
-
@config.capsules.values.map(&:weights)
|
|
266
|
-
end
|
|
267
|
-
|
|
268
277
|
def to_json
|
|
269
278
|
# this data changes infrequently so dump it to a string
|
|
270
279
|
# now so we don't need to dump it every heartbeat.
|
|
@@ -11,6 +11,7 @@ module Sidekiq::Middleware::I18n
|
|
|
11
11
|
# to be sent to Sidekiq.
|
|
12
12
|
class Client
|
|
13
13
|
include Sidekiq::ClientMiddleware
|
|
14
|
+
|
|
14
15
|
def call(_jobclass, job, _queue, _redis)
|
|
15
16
|
job["locale"] ||= I18n.locale
|
|
16
17
|
yield
|
|
@@ -20,6 +21,7 @@ module Sidekiq::Middleware::I18n
|
|
|
20
21
|
# Pull the msg locale out and set the current thread to use it.
|
|
21
22
|
class Server
|
|
22
23
|
include Sidekiq::ServerMiddleware
|
|
24
|
+
|
|
23
25
|
def call(_jobclass, job, _queue, &block)
|
|
24
26
|
I18n.with_locale(job.fetch("locale", I18n.default_locale), &block)
|
|
25
27
|
end
|
data/lib/sidekiq/monitor.rb
CHANGED
|
@@ -49,14 +49,10 @@ class Sidekiq::Monitor
|
|
|
49
49
|
puts "---- Processes (#{process_set.size}) ----"
|
|
50
50
|
process_set.each_with_index do |process, index|
|
|
51
51
|
# Keep compatibility with legacy versions since we don't want to break sidekiqmon during rolling upgrades or downgrades.
|
|
52
|
-
#
|
|
53
|
-
# Before:
|
|
54
|
-
# ["default", "critical"]
|
|
55
|
-
#
|
|
56
|
-
# After:
|
|
57
|
-
# {"default" => 1, "critical" => 10}
|
|
58
52
|
queues =
|
|
59
|
-
if process["
|
|
53
|
+
if process["capsules"] # 8.0.6+
|
|
54
|
+
process["capsules"].values.map { |x| x["weights"].keys.join(", ") }
|
|
55
|
+
elsif process["weights"]
|
|
60
56
|
process["weights"].sort_by { |queue| queue[0] }.map { |capsule| capsule.map { |name, weight| (weight > 0) ? "#{name}: #{weight}" : name }.join(", ") }
|
|
61
57
|
else
|
|
62
58
|
process["queues"].sort
|
|
@@ -105,7 +101,7 @@ class Sidekiq::Monitor
|
|
|
105
101
|
out << line
|
|
106
102
|
line = " " * pad
|
|
107
103
|
end
|
|
108
|
-
line << value + "
|
|
104
|
+
line << value + "; "
|
|
109
105
|
end
|
|
110
106
|
out << line[0..-3]
|
|
111
107
|
out.join("\n")
|
data/lib/sidekiq/profiler.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Sidekiq
|
|
|
23
23
|
|
|
24
24
|
size = symbolized_options.delete(:size) || 5
|
|
25
25
|
pool_timeout = symbolized_options.delete(:pool_timeout) || 1
|
|
26
|
-
|
|
26
|
+
symbolized_options.delete(:pool_name)
|
|
27
27
|
|
|
28
28
|
# Default timeout in redis-client is 1 second, which can be too aggressive
|
|
29
29
|
# if the Sidekiq process is CPU-bound. With 10-15 threads and a thread quantum of 100ms,
|
|
@@ -33,7 +33,7 @@ module Sidekiq
|
|
|
33
33
|
symbolized_options[:timeout] ||= 3
|
|
34
34
|
|
|
35
35
|
redis_config = Sidekiq::RedisClientAdapter.new(symbolized_options)
|
|
36
|
-
ConnectionPool.new(timeout: pool_timeout, size: size
|
|
36
|
+
ConnectionPool.new(timeout: pool_timeout, size: size) do
|
|
37
37
|
redis_config.new_client
|
|
38
38
|
end
|
|
39
39
|
end
|
data/lib/sidekiq/ring_buffer.rb
CHANGED
data/lib/sidekiq/scheduled.rb
CHANGED
|
@@ -72,6 +72,7 @@ module Sidekiq
|
|
|
72
72
|
include Sidekiq::Component
|
|
73
73
|
|
|
74
74
|
INITIAL_WAIT = 10
|
|
75
|
+
attr_accessor :rnd
|
|
75
76
|
|
|
76
77
|
def initialize(config)
|
|
77
78
|
@config = config
|
|
@@ -80,6 +81,7 @@ module Sidekiq
|
|
|
80
81
|
@done = false
|
|
81
82
|
@thread = nil
|
|
82
83
|
@count_calls = 0
|
|
84
|
+
@rnd = Random.new
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
# Shut down this instance, will pause until the thread is dead.
|
|
@@ -115,9 +117,9 @@ module Sidekiq
|
|
|
115
117
|
private
|
|
116
118
|
|
|
117
119
|
def wait
|
|
118
|
-
@sleeper.pop(random_poll_interval)
|
|
120
|
+
@sleeper.pop(timeout: random_poll_interval)
|
|
119
121
|
rescue Timeout::Error
|
|
120
|
-
#
|
|
122
|
+
# TODO move to exception: false
|
|
121
123
|
rescue => ex
|
|
122
124
|
# if poll_interval_average hasn't been calculated yet, we can
|
|
123
125
|
# raise an error trying to reach Redis.
|
|
@@ -151,11 +153,11 @@ module Sidekiq
|
|
|
151
153
|
|
|
152
154
|
if count < 10
|
|
153
155
|
# For small clusters, calculate a random interval that is ±50% the desired average.
|
|
154
|
-
interval * rand + interval.to_f / 2
|
|
156
|
+
interval * @rnd.rand + interval.to_f / 2
|
|
155
157
|
else
|
|
156
158
|
# With 10+ processes, we should have enough randomness to get decent polling
|
|
157
159
|
# across the entire timespan
|
|
158
|
-
interval * rand
|
|
160
|
+
interval * @rnd.rand * 2
|
|
159
161
|
end
|
|
160
162
|
end
|
|
161
163
|
|
|
@@ -223,7 +225,7 @@ module Sidekiq
|
|
|
223
225
|
total += INITIAL_WAIT unless @config[:poll_interval_average]
|
|
224
226
|
total += (5 * rand)
|
|
225
227
|
|
|
226
|
-
@sleeper.pop(total)
|
|
228
|
+
@sleeper.pop(timeout: total)
|
|
227
229
|
rescue Timeout::Error
|
|
228
230
|
ensure
|
|
229
231
|
# periodically clean out the `processes` set in Redis which can collect
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
|
@@ -117,7 +117,7 @@ module Sidekiq
|
|
|
117
117
|
if content.is_a? Symbol
|
|
118
118
|
unless respond_to?(:"_erb_#{content}")
|
|
119
119
|
views = options[:views] || Web.views
|
|
120
|
-
filename = "#{views}/#{content}.erb"
|
|
120
|
+
filename = "#{views}/#{content}.html.erb"
|
|
121
121
|
src = ERB.new(File.read(filename)).src
|
|
122
122
|
|
|
123
123
|
# Need to use lineno less by 1 because erb generates a
|
|
@@ -318,6 +318,16 @@ module Sidekiq
|
|
|
318
318
|
redirect_with_query("#{root_path}scheduled")
|
|
319
319
|
end
|
|
320
320
|
|
|
321
|
+
post "/scheduled/all/delete" do
|
|
322
|
+
Sidekiq::ScheduledSet.new.clear
|
|
323
|
+
redirect "#{root_path}scheduled"
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
post "/scheduled/all/add_to_queue" do
|
|
327
|
+
Sidekiq::ScheduledSet.new.each(&:add_to_queue)
|
|
328
|
+
redirect "#{root_path}scheduled"
|
|
329
|
+
end
|
|
330
|
+
|
|
321
331
|
get "/dashboard/stats" do
|
|
322
332
|
redirect "#{root_path}stats"
|
|
323
333
|
end
|
data/lib/sidekiq/web/config.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "sidekiq/web/csrf_protection"
|
|
4
|
-
|
|
5
3
|
module Sidekiq
|
|
6
4
|
class Web
|
|
7
5
|
##
|
|
@@ -24,10 +22,7 @@ module Sidekiq
|
|
|
24
22
|
# and very difficult for us to vendor or provide ourselves. If you are worried
|
|
25
23
|
# about data security and wish to self-host, you can change these URLs.
|
|
26
24
|
profile_view_url: "https://profiler.firefox.com/public/%s",
|
|
27
|
-
profile_store_url: "https://api.profiler.firefox.com/compressed-store"
|
|
28
|
-
# Will be false in Sidekiq 9.0.
|
|
29
|
-
# CSRF is unnecessary if you are using SameSite=(Strict|Lax) cookies.
|
|
30
|
-
csrf: true
|
|
25
|
+
profile_store_url: "https://api.profiler.firefox.com/compressed-store"
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
##
|
|
@@ -54,11 +49,13 @@ module Sidekiq
|
|
|
54
49
|
|
|
55
50
|
# Adds the "Back to App" link in the header
|
|
56
51
|
attr_accessor :app_url
|
|
52
|
+
attr_accessor :assets_path
|
|
57
53
|
|
|
58
54
|
def initialize
|
|
59
55
|
@options = OPTIONS.dup
|
|
60
56
|
@locales = LOCALES
|
|
61
57
|
@views = VIEWS
|
|
58
|
+
@assets_path = ASSETS
|
|
62
59
|
@tabs = DEFAULT_TABS.dup
|
|
63
60
|
@middlewares = []
|
|
64
61
|
@custom_job_info_rows = []
|
data/lib/sidekiq/web/helpers.rb
CHANGED
|
@@ -122,8 +122,8 @@ module Sidekiq
|
|
|
122
122
|
resultset
|
|
123
123
|
end
|
|
124
124
|
|
|
125
|
-
def filtering(which)
|
|
126
|
-
erb(:filtering, locals: {which:
|
|
125
|
+
def filtering(which, placeholder_key: "AnyJobContent", label_key: "Filter")
|
|
126
|
+
erb(:filtering, locals: {which:, placeholder_key:, label_key:})
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
def filter_link(jid, within = "retries")
|
|
@@ -256,14 +256,6 @@ module Sidekiq
|
|
|
256
256
|
end
|
|
257
257
|
end
|
|
258
258
|
|
|
259
|
-
def busy_weights(capsule_weights)
|
|
260
|
-
# backwards compat with 7.0.0, remove in 7.1
|
|
261
|
-
cw = [capsule_weights].flatten
|
|
262
|
-
cw.map { |hash|
|
|
263
|
-
hash.map { |name, weight| (weight > 0) ? +name << ": " << weight.to_s : name }.join(", ")
|
|
264
|
-
}.join("; ")
|
|
265
|
-
end
|
|
266
|
-
|
|
267
259
|
def stats
|
|
268
260
|
@stats ||= Sidekiq::Stats.new
|
|
269
261
|
end
|
|
@@ -337,7 +329,7 @@ module Sidekiq
|
|
|
337
329
|
end
|
|
338
330
|
|
|
339
331
|
def csrf_tag
|
|
340
|
-
"
|
|
332
|
+
""
|
|
341
333
|
end
|
|
342
334
|
|
|
343
335
|
def csp_nonce
|