sidekiq 8.0.6 → 8.0.8
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 +31 -0
- data/lib/sidekiq/api.rb +2 -1
- data/lib/sidekiq/client.rb +15 -1
- data/lib/sidekiq/component.rb +2 -1
- data/lib/sidekiq/config.rb +3 -4
- data/lib/sidekiq/job/iterable.rb +28 -12
- data/lib/sidekiq/job.rb +2 -2
- data/lib/sidekiq/job_logger.rb +1 -1
- data/lib/sidekiq/job_retry.rb +16 -5
- data/lib/sidekiq/loader.rb +57 -0
- data/lib/sidekiq/logger.rb +16 -9
- data/lib/sidekiq/middleware/current_attributes.rb +2 -1
- data/lib/sidekiq/rails.rb +3 -1
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +3 -3
- data/lib/sidekiq.rb +5 -0
- data/web/assets/images/logo.png +0 -0
- data/web/assets/images/status.png +0 -0
- data/web/assets/javascripts/application.js +20 -13
- data/web/assets/stylesheets/style.css +0 -7
- data/web/locales/uk.yml +5 -5
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a1e8c90888b4135f21e4dfef66fd9ad9ac8c72ab267599a8452f4bd172234a2
|
4
|
+
data.tar.gz: fa83e70c818fc3b25441e946c1a093a2d9a5f4515ee2bd88522cbafcb8097973
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ea8ac9585538723d941af6ce9150933669705cf1e3459dcea8989d073d234c4e233e74314a5a682e3111e1290a69671051e847b5ee97970c1edd08293e14bbc
|
7
|
+
data.tar.gz: 0b253cd035132f786613fbb97440f5d16f48717aedaa7f50865e0e261ce0fc17b64885bea3cdeb5aabe72258c06ed013891d83655bdcf842fc1a261d1b0aa985
|
data/Changes.md
CHANGED
@@ -2,6 +2,37 @@
|
|
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.0.8
|
6
|
+
----------
|
7
|
+
|
8
|
+
- Allow an optional global iteration max runtime. After executing for this length of time,
|
9
|
+
Sidekiq will re-queue the job to continue execution at a later time [#6819, fatkodima]
|
10
|
+
```ruby
|
11
|
+
Sidekiq.configure_server do |cfg|
|
12
|
+
cfg[:max_iteration_runtime] = 600 # ten minutes
|
13
|
+
end
|
14
|
+
```
|
15
|
+
- Add `discarded_at` attribute when discarding a job so death handlers can distinguish between
|
16
|
+
a job which was killed and one that was discarded. [#6820, gstokkink]
|
17
|
+
- `perform_bulk` now accepts an `:at` array of times to schedule each job at the corresponding time.
|
18
|
+
`perform_bulk(args: [[1], [2]], at: [Time.now, Time.now + 1])` [#6790, fatkodima]
|
19
|
+
- `perform_bulk` now accepts a `:spread_interval` value to schedule jobs over
|
20
|
+
the next N seconds. `perform_bulk(..., spread_interval: 60)` [#6792, fatkodima]
|
21
|
+
- Fix unintended display of flash messages in the Web UI due to session key collision
|
22
|
+
- Add support for lazy load hooks [#6825]
|
23
|
+
|
24
|
+
8.0.7
|
25
|
+
----------
|
26
|
+
|
27
|
+
- The `:discard` option for `sidekiq_retries_exhausted` and `sidekiq_retry_in`
|
28
|
+
now calls death handlers, otherwise it could break other Sidekiq
|
29
|
+
functionality. [#6741]
|
30
|
+
- Provide a Plain log formatter which does not colorize output [#6778]
|
31
|
+
- Job iteration now exposes `current_object` for easy access within the `around_iteration` callback [#6774]
|
32
|
+
- Fix JS race condition which could skip confirmation dialogs when Live Polling [#6768]
|
33
|
+
- Fix edge case which could lose CurrentAttributes [#6767]
|
34
|
+
- Update UK locale [#6776]
|
35
|
+
|
5
36
|
8.0.6
|
6
37
|
----------
|
7
38
|
|
data/lib/sidekiq/api.rb
CHANGED
@@ -1168,7 +1168,6 @@ module Sidekiq
|
|
1168
1168
|
# # thread_id is a unique identifier per thread
|
1169
1169
|
# # work is a `Sidekiq::Work` instance that has the following accessor methods.
|
1170
1170
|
# # [work.queue, work.run_at, work.payload]
|
1171
|
-
# # run_at is an epoch Integer.
|
1172
1171
|
# end
|
1173
1172
|
#
|
1174
1173
|
class WorkSet
|
@@ -1322,3 +1321,5 @@ module Sidekiq
|
|
1322
1321
|
end
|
1323
1322
|
end
|
1324
1323
|
end
|
1324
|
+
|
1325
|
+
Sidekiq.loader.run_load_hooks(:api)
|
data/lib/sidekiq/client.rb
CHANGED
@@ -117,6 +117,9 @@ module Sidekiq
|
|
117
117
|
# larger than 1000 but YMMV based on network quality, size of job args, etc.
|
118
118
|
# A large number of jobs can cause a bit of Redis command processing latency.
|
119
119
|
#
|
120
|
+
# Accepts an additional `:spread_interval` option (in seconds) to randomly spread
|
121
|
+
# the jobs schedule times over the specified interval.
|
122
|
+
#
|
120
123
|
# Takes the same arguments as #push except that args is expected to be
|
121
124
|
# an Array of Arrays. All other keys are duplicated for each job. Each job
|
122
125
|
# is run through the client middleware pipeline and each job gets its own Job ID
|
@@ -131,13 +134,24 @@ module Sidekiq
|
|
131
134
|
def push_bulk(items)
|
132
135
|
batch_size = items.delete(:batch_size) || items.delete("batch_size") || 1_000
|
133
136
|
args = items["args"]
|
134
|
-
at = items.delete("at")
|
137
|
+
at = items.delete("at") || items.delete(:at)
|
135
138
|
raise ArgumentError, "Job 'at' must be a Numeric or an Array of Numeric timestamps" if at && (Array(at).empty? || !Array(at).all? { |entry| entry.is_a?(Numeric) })
|
136
139
|
raise ArgumentError, "Job 'at' Array must have same size as 'args' Array" if at.is_a?(Array) && at.size != args.size
|
137
140
|
|
138
141
|
jid = items.delete("jid")
|
139
142
|
raise ArgumentError, "Explicitly passing 'jid' when pushing more than one job is not supported" if jid && args.size > 1
|
140
143
|
|
144
|
+
spread_interval = items.delete(:spread_interval) || items.delete("spread_interval")
|
145
|
+
raise ArgumentError, "Jobs 'spread_interval' must be a positive Numeric" if spread_interval && (!spread_interval.is_a?(Numeric) || spread_interval <= 0)
|
146
|
+
raise ArgumentError, "Only one of 'at' or 'spread_interval' can be provided" if at && spread_interval
|
147
|
+
|
148
|
+
if !at && spread_interval
|
149
|
+
# Do not use spread interval smaller than pooling interval.
|
150
|
+
spread_interval = [spread_interval, 5].max
|
151
|
+
now = Time.now.to_f
|
152
|
+
at = args.map { now + rand * spread_interval }
|
153
|
+
end
|
154
|
+
|
141
155
|
normed = normalize_item(items)
|
142
156
|
slice_index = 0
|
143
157
|
result = args.each_slice(batch_size).flat_map do |slice|
|
data/lib/sidekiq/component.rb
CHANGED
@@ -19,7 +19,8 @@ module Sidekiq
|
|
19
19
|
DEFAULT_THREAD_PRIORITY = -1
|
20
20
|
|
21
21
|
##
|
22
|
-
# Sidekiq::Component
|
22
|
+
# Sidekiq::Component provides a set of utility methods depending only
|
23
|
+
# on Sidekiq::Config. It assumes a config instance is available at @config.
|
23
24
|
module Component # :nodoc:
|
24
25
|
attr_reader :config
|
25
26
|
|
data/lib/sidekiq/config.rb
CHANGED
@@ -17,10 +17,9 @@ module Sidekiq
|
|
17
17
|
poll_interval_average: nil,
|
18
18
|
average_scheduled_poll_interval: 5,
|
19
19
|
on_complex_arguments: :raise,
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
},
|
20
|
+
# if the Iterable job runs longer than this value (in seconds), then the job
|
21
|
+
# will be interrupted after the current iteration and re-enqueued at the back of the queue
|
22
|
+
max_iteration_runtime: nil,
|
24
23
|
error_handlers: [],
|
25
24
|
death_handlers: [],
|
26
25
|
lifecycle_events: {
|
data/lib/sidekiq/job/iterable.rb
CHANGED
@@ -32,8 +32,14 @@ module Sidekiq
|
|
32
32
|
@_runtime = 0
|
33
33
|
@_args = nil
|
34
34
|
@_cancelled = nil
|
35
|
+
@current_object = nil
|
35
36
|
end
|
36
37
|
|
38
|
+
# Access to the current object while iterating.
|
39
|
+
# This value is not reset so the latest element is
|
40
|
+
# explicitly available to cleanup/complete callbacks.
|
41
|
+
attr_reader :current_object
|
42
|
+
|
37
43
|
def arguments
|
38
44
|
@_args
|
39
45
|
end
|
@@ -137,7 +143,7 @@ module Sidekiq
|
|
137
143
|
fetch_previous_iteration_state
|
138
144
|
|
139
145
|
@_executions += 1
|
140
|
-
@_start_time =
|
146
|
+
@_start_time = mono_now
|
141
147
|
|
142
148
|
enumerator = build_enumerator(*args, cursor: @_cursor)
|
143
149
|
unless enumerator
|
@@ -198,16 +204,17 @@ module Sidekiq
|
|
198
204
|
|
199
205
|
time_limit = Sidekiq.default_configuration[:timeout]
|
200
206
|
found_record = false
|
201
|
-
state_flushed_at =
|
207
|
+
state_flushed_at = mono_now
|
202
208
|
|
203
209
|
enumerator.each do |object, cursor|
|
204
210
|
found_record = true
|
205
211
|
@_cursor = cursor
|
212
|
+
@current_object = object
|
206
213
|
|
207
|
-
|
208
|
-
if
|
214
|
+
interrupt_job = interrupted? || should_interrupt?
|
215
|
+
if mono_now - state_flushed_at >= STATE_FLUSH_INTERVAL || interrupt_job
|
209
216
|
_, _, cancelled = flush_state
|
210
|
-
state_flushed_at =
|
217
|
+
state_flushed_at = mono_now
|
211
218
|
if cancelled
|
212
219
|
@_cancelled = true
|
213
220
|
on_cancel
|
@@ -216,9 +223,9 @@ module Sidekiq
|
|
216
223
|
end
|
217
224
|
end
|
218
225
|
|
219
|
-
return false if
|
226
|
+
return false if interrupt_job
|
220
227
|
|
221
|
-
verify_iteration_time(time_limit
|
228
|
+
verify_iteration_time(time_limit) do
|
222
229
|
around_iteration do
|
223
230
|
each_iteration(object, *arguments)
|
224
231
|
rescue Exception
|
@@ -231,16 +238,16 @@ module Sidekiq
|
|
231
238
|
logger.debug("Enumerator found nothing to iterate!") unless found_record
|
232
239
|
true
|
233
240
|
ensure
|
234
|
-
@_runtime += (
|
241
|
+
@_runtime += (mono_now - @_start_time)
|
235
242
|
end
|
236
243
|
|
237
|
-
def verify_iteration_time(time_limit
|
238
|
-
start =
|
244
|
+
def verify_iteration_time(time_limit)
|
245
|
+
start = mono_now
|
239
246
|
yield
|
240
|
-
finish =
|
247
|
+
finish = mono_now
|
241
248
|
total = finish - start
|
242
249
|
if total > time_limit
|
243
|
-
logger.warn { "Iteration took longer (%.2f) than Sidekiq's shutdown timeout (%d)
|
250
|
+
logger.warn { "Iteration took longer (%.2f) than Sidekiq's shutdown timeout (%d). This can lead to job processing problems during deploys" % [total, time_limit] }
|
244
251
|
end
|
245
252
|
end
|
246
253
|
|
@@ -266,6 +273,11 @@ module Sidekiq
|
|
266
273
|
end
|
267
274
|
end
|
268
275
|
|
276
|
+
def should_interrupt?
|
277
|
+
max_iteration_runtime = Sidekiq.default_configuration[:max_iteration_runtime]
|
278
|
+
max_iteration_runtime && (mono_now - @_start_time > max_iteration_runtime)
|
279
|
+
end
|
280
|
+
|
269
281
|
def flush_state
|
270
282
|
key = iteration_key
|
271
283
|
state = {
|
@@ -301,6 +313,10 @@ module Sidekiq
|
|
301
313
|
raise "Unexpected thrown value: #{completed.inspect}"
|
302
314
|
end
|
303
315
|
end
|
316
|
+
|
317
|
+
def mono_now
|
318
|
+
::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
319
|
+
end
|
304
320
|
end
|
305
321
|
end
|
306
322
|
end
|
data/lib/sidekiq/job.rb
CHANGED
@@ -248,9 +248,9 @@ module Sidekiq
|
|
248
248
|
end
|
249
249
|
alias_method :perform_sync, :perform_inline
|
250
250
|
|
251
|
-
def perform_bulk(args,
|
251
|
+
def perform_bulk(args, **options)
|
252
252
|
client = @klass.build_client
|
253
|
-
client.push_bulk(@opts.merge("class" => @klass, "args" => args,
|
253
|
+
client.push_bulk(@opts.merge({"class" => @klass, "args" => args}, options))
|
254
254
|
end
|
255
255
|
|
256
256
|
# +interval+ must be a timestamp, numeric or something that acts
|
data/lib/sidekiq/job_logger.rb
CHANGED
@@ -27,7 +27,7 @@ module Sidekiq
|
|
27
27
|
# attribute to expose the underlying thing.
|
28
28
|
h = {
|
29
29
|
jid: job_hash["jid"],
|
30
|
-
class: job_hash["
|
30
|
+
class: job_hash["wrapped"] || job_hash["class"]
|
31
31
|
}
|
32
32
|
h[:bid] = job_hash["bid"] if job_hash.has_key?("bid")
|
33
33
|
h[:tags] = job_hash["tags"] if job_hash.has_key?("tags")
|
data/lib/sidekiq/job_retry.rb
CHANGED
@@ -186,7 +186,9 @@ module Sidekiq
|
|
186
186
|
strategy, delay = delay_for(jobinst, count, exception, msg)
|
187
187
|
case strategy
|
188
188
|
when :discard
|
189
|
-
|
189
|
+
msg["discarded_at"] = now_ms
|
190
|
+
|
191
|
+
return run_death_handlers(msg, exception)
|
190
192
|
when :kill
|
191
193
|
return retries_exhausted(jobinst, msg, exception)
|
192
194
|
end
|
@@ -255,13 +257,22 @@ module Sidekiq
|
|
255
257
|
handle_exception(e, {context: "Error calling retries_exhausted", job: msg})
|
256
258
|
end
|
257
259
|
|
258
|
-
|
259
|
-
|
260
|
+
discarded = msg["dead"] == false || rv == :discard
|
261
|
+
|
262
|
+
if discarded
|
263
|
+
msg["discarded_at"] = now_ms
|
264
|
+
else
|
265
|
+
send_to_morgue(msg)
|
266
|
+
end
|
267
|
+
|
268
|
+
run_death_handlers(msg, exception)
|
269
|
+
end
|
260
270
|
|
271
|
+
def run_death_handlers(job, exception)
|
261
272
|
@capsule.config.death_handlers.each do |handler|
|
262
|
-
handler.call(
|
273
|
+
handler.call(job, exception)
|
263
274
|
rescue => e
|
264
|
-
handle_exception(e, {context: "Error calling death handler", job:
|
275
|
+
handle_exception(e, {context: "Error calling death handler", job: job})
|
265
276
|
end
|
266
277
|
end
|
267
278
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
require "sidekiq/component"
|
3
|
+
|
4
|
+
class Loader
|
5
|
+
include Sidekiq::Component
|
6
|
+
|
7
|
+
def initialize(cfg = Sidekiq.default_configuration)
|
8
|
+
@config = cfg
|
9
|
+
@load_hooks = Hash.new { |h, k| h[k] = [] }
|
10
|
+
@loaded = Set.new
|
11
|
+
@lock = Mutex.new
|
12
|
+
end
|
13
|
+
|
14
|
+
# Declares a block that will be executed when a Sidekiq component is fully
|
15
|
+
# loaded. If the component has already loaded, the block is executed
|
16
|
+
# immediately.
|
17
|
+
#
|
18
|
+
# Sidekiq.loader.on_load(:api) do
|
19
|
+
# # extend the sidekiq API
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
def on_load(name, &block)
|
23
|
+
# we don't want to hold the lock while calling the block
|
24
|
+
to_run = nil
|
25
|
+
|
26
|
+
@lock.synchronize do
|
27
|
+
if @loaded.include?(name)
|
28
|
+
to_run = block
|
29
|
+
else
|
30
|
+
@load_hooks[name] << block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
to_run&.call
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
|
38
|
+
# Executes all blocks registered to +name+ via on_load.
|
39
|
+
#
|
40
|
+
# Sidekiq.loader.run_load_hooks(:api)
|
41
|
+
#
|
42
|
+
# In the case of the above example, it will execute all hooks registered for +:api+.
|
43
|
+
#
|
44
|
+
def run_load_hooks(name)
|
45
|
+
hks = @lock.synchronize do
|
46
|
+
@loaded << name
|
47
|
+
@load_hooks.delete(name)
|
48
|
+
end
|
49
|
+
|
50
|
+
hks&.each do |blk|
|
51
|
+
blk.call
|
52
|
+
rescue => ex
|
53
|
+
handle_exception(ex, hook: name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/sidekiq/logger.rb
CHANGED
@@ -24,14 +24,15 @@ module Sidekiq
|
|
24
24
|
|
25
25
|
class Logger < ::Logger
|
26
26
|
module Formatters
|
27
|
-
COLORS = {
|
28
|
-
"DEBUG" => "\e[1;32mDEBUG\e[0m", # green
|
29
|
-
"INFO" => "\e[1;34mINFO \e[0m", # blue
|
30
|
-
"WARN" => "\e[1;33mWARN \e[0m", # yellow
|
31
|
-
"ERROR" => "\e[1;31mERROR\e[0m", # red
|
32
|
-
"FATAL" => "\e[1;35mFATAL\e[0m" # pink
|
33
|
-
}
|
34
27
|
class Base < ::Logger::Formatter
|
28
|
+
COLORS = {
|
29
|
+
"DEBUG" => "\e[1;32mDEBUG\e[0m", # green
|
30
|
+
"INFO" => "\e[1;34mINFO \e[0m", # blue
|
31
|
+
"WARN" => "\e[1;33mWARN \e[0m", # yellow
|
32
|
+
"ERROR" => "\e[1;31mERROR\e[0m", # red
|
33
|
+
"FATAL" => "\e[1;35mFATAL\e[0m" # pink
|
34
|
+
}
|
35
|
+
|
35
36
|
def tid
|
36
37
|
Thread.current["sidekiq_tid"] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
|
37
38
|
end
|
@@ -50,13 +51,19 @@ module Sidekiq
|
|
50
51
|
|
51
52
|
class Pretty < Base
|
52
53
|
def call(severity, time, program_name, message)
|
53
|
-
"#{
|
54
|
+
"#{COLORS[severity]} #{time.utc.iso8601(3)} pid=#{::Process.pid} tid=#{tid}#{format_context}: #{message}\n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class Plain < Base
|
59
|
+
def call(severity, time, program_name, message)
|
60
|
+
"#{severity} #{time.utc.iso8601(3)} pid=#{::Process.pid} tid=#{tid}#{format_context}: #{message}\n"
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
57
64
|
class WithoutTimestamp < Pretty
|
58
65
|
def call(severity, time, program_name, message)
|
59
|
-
"#{
|
66
|
+
"#{COLORS[severity]} pid=#{::Process.pid} tid=#{tid}#{format_context}: #{message}\n"
|
60
67
|
end
|
61
68
|
end
|
62
69
|
|
@@ -50,7 +50,7 @@ module Sidekiq
|
|
50
50
|
@cattrs = cattrs
|
51
51
|
end
|
52
52
|
|
53
|
-
def call(_, job,
|
53
|
+
def call(_, job, *, &block)
|
54
54
|
klass_attrs = {}
|
55
55
|
|
56
56
|
@cattrs.each do |(key, strklass)|
|
@@ -93,6 +93,7 @@ module Sidekiq
|
|
93
93
|
def persist(klass_or_array, config = Sidekiq.default_configuration)
|
94
94
|
cattrs = build_cattrs_hash(klass_or_array)
|
95
95
|
|
96
|
+
config.client_middleware.prepend Load, cattrs
|
96
97
|
config.client_middleware.add Save, cattrs
|
97
98
|
config.server_middleware.prepend Load, cattrs
|
98
99
|
end
|
data/lib/sidekiq/rails.rb
CHANGED
@@ -48,8 +48,10 @@ module Sidekiq
|
|
48
48
|
unless ::Rails.logger == config.logger || ::ActiveSupport::Logger.logger_outputs_to?(::Rails.logger, $stdout)
|
49
49
|
if ::Rails.logger.respond_to?(:broadcast_to)
|
50
50
|
::Rails.logger.broadcast_to(config.logger)
|
51
|
-
|
51
|
+
elsif ::ActiveSupport::Logger.respond_to?(:broadcast)
|
52
52
|
::Rails.logger.extend(::ActiveSupport::Logger.broadcast(config.logger))
|
53
|
+
else
|
54
|
+
::Rails.logger = ::ActiveSupport::BroadcastLogger.new(::Rails.logger, config.logger)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
@@ -102,15 +102,15 @@ module Sidekiq
|
|
102
102
|
def flash
|
103
103
|
msg = yield
|
104
104
|
logger.info msg
|
105
|
-
session[:
|
105
|
+
session[:skq_flash] = msg
|
106
106
|
end
|
107
107
|
|
108
108
|
def flash?
|
109
|
-
session&.[](:
|
109
|
+
session&.[](:skq_flash)
|
110
110
|
end
|
111
111
|
|
112
112
|
def get_flash
|
113
|
-
@flash ||= session.delete(:
|
113
|
+
@flash ||= session.delete(:skq_flash)
|
114
114
|
end
|
115
115
|
|
116
116
|
def erb(content, options = {})
|
data/lib/sidekiq.rb
CHANGED
@@ -29,6 +29,7 @@ end
|
|
29
29
|
|
30
30
|
require "sidekiq/config"
|
31
31
|
require "sidekiq/logger"
|
32
|
+
require "sidekiq/loader"
|
32
33
|
require "sidekiq/client"
|
33
34
|
require "sidekiq/transaction_aware_client"
|
34
35
|
require "sidekiq/job"
|
@@ -94,6 +95,10 @@ module Sidekiq
|
|
94
95
|
default_configuration.logger
|
95
96
|
end
|
96
97
|
|
98
|
+
def self.loader
|
99
|
+
@loader ||= Loader.new
|
100
|
+
end
|
101
|
+
|
97
102
|
def self.configure_server(&block)
|
98
103
|
(@config_blocks ||= []) << block
|
99
104
|
yield default_configuration if server?
|
data/web/assets/images/logo.png
CHANGED
File without changes
|
File without changes
|
@@ -18,15 +18,6 @@ function addListeners() {
|
|
18
18
|
})
|
19
19
|
});
|
20
20
|
|
21
|
-
document.querySelectorAll("input[data-confirm]").forEach(node => {
|
22
|
-
node.addEventListener("click", event => {
|
23
|
-
if (!window.confirm(node.getAttribute("data-confirm"))) {
|
24
|
-
event.preventDefault();
|
25
|
-
event.stopPropagation();
|
26
|
-
}
|
27
|
-
})
|
28
|
-
})
|
29
|
-
|
30
21
|
document.querySelectorAll("[data-toggle]").forEach(node => {
|
31
22
|
node.addEventListener("click", addDataToggleListeners)
|
32
23
|
})
|
@@ -67,7 +58,7 @@ function addPollingListeners(_event) {
|
|
67
58
|
|
68
59
|
function addDataToggleListeners(event) {
|
69
60
|
var source = event.target || event.srcElement;
|
70
|
-
var targName = source.
|
61
|
+
var targName = source.dataset.toggle;
|
71
62
|
var full = document.getElementById(targName);
|
72
63
|
full.classList.toggle("is-open");
|
73
64
|
}
|
@@ -90,7 +81,7 @@ function addShiftClickListeners() {
|
|
90
81
|
}
|
91
82
|
|
92
83
|
function updateFuzzyTimes() {
|
93
|
-
var locale = document.body.
|
84
|
+
var locale = document.body.dataset.locale;
|
94
85
|
var parts = locale.split('-');
|
95
86
|
if (typeof parts[1] !== 'undefined') {
|
96
87
|
parts[1] = parts[1].toUpperCase();
|
@@ -105,7 +96,7 @@ function updateFuzzyTimes() {
|
|
105
96
|
function updateNumbers() {
|
106
97
|
document.querySelectorAll("[data-nwp]").forEach(node => {
|
107
98
|
let number = parseFloat(node.textContent);
|
108
|
-
let precision = parseInt(node.dataset
|
99
|
+
let precision = parseInt(node.dataset.nwp || 0);
|
109
100
|
if (typeof number === "number") {
|
110
101
|
let formatted = number.toLocaleString(undefined, {
|
111
102
|
minimumFractionDigits: precision,
|
@@ -178,4 +169,20 @@ function updateLocale(event) {
|
|
178
169
|
|
179
170
|
function updateProgressBars() {
|
180
171
|
document.querySelectorAll('.progress-bar').forEach(bar => { bar.style.width = bar.dataset.width + "%"})
|
181
|
-
}
|
172
|
+
}
|
173
|
+
|
174
|
+
function handleConfirmDialog (event) {
|
175
|
+
const target = event.target
|
176
|
+
|
177
|
+
if (target.localName !== "input") { return }
|
178
|
+
const confirmMessage = target.dataset.confirm
|
179
|
+
|
180
|
+
if (confirmMessage === undefined) { return }
|
181
|
+
|
182
|
+
if (!window.confirm(confirmMessage)) {
|
183
|
+
event.preventDefault()
|
184
|
+
event.stopPropagation()
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
document.addEventListener("click", handleConfirmDialog)
|
@@ -29,8 +29,6 @@
|
|
29
29
|
|
30
30
|
*, *::before, *::after { box-sizing: border-box; }
|
31
31
|
|
32
|
-
::selection { background: var(--color-selected); }
|
33
|
-
|
34
32
|
:focus-visible {
|
35
33
|
outline: 1px solid oklch(from var(--color-primary) l c h / 50%);
|
36
34
|
}
|
@@ -567,7 +565,6 @@ body > footer .nav {
|
|
567
565
|
--color-border: oklch(25% 0.01 256);
|
568
566
|
--color-input-border: oklch(31% 0.01 256);
|
569
567
|
--color-selected: oklch(27% 0.01 256);
|
570
|
-
--color-selected-text: oklch(55% 0.11 45);
|
571
568
|
--color-table-bg-alt: oklch(24% 0.01 256);
|
572
569
|
--color-shadow: oklch(9% 0.01 256 / 10%);
|
573
570
|
--color-text: oklch(75% 0.01 256);
|
@@ -616,10 +613,6 @@ body > footer .nav {
|
|
616
613
|
.label-info { background: var(--color-info); }
|
617
614
|
.label-danger { background: var(--color-danger); }
|
618
615
|
.label-warning { background: var(--color-warning); }
|
619
|
-
|
620
|
-
td.box::selection {
|
621
|
-
background-color: var(--color-selected-text);
|
622
|
-
}
|
623
616
|
}
|
624
617
|
|
625
618
|
@media (max-width: 800px) { :root { --font-size: 14px; } }
|
data/web/locales/uk.yml
CHANGED
@@ -14,8 +14,8 @@ uk:
|
|
14
14
|
CreatedAt: Створено
|
15
15
|
CurrentMessagesInQueue: Поточні задачі у черзі <span class='title'>%{queue}</span>
|
16
16
|
Dashboard: Панель керування
|
17
|
-
Dead:
|
18
|
-
DeadJobs:
|
17
|
+
Dead: Зупинених
|
18
|
+
DeadJobs: Зупинені задачі
|
19
19
|
Delete: Видалити
|
20
20
|
DeleteAll: Видалити усі
|
21
21
|
Deploy: Деплой
|
@@ -33,8 +33,8 @@ uk:
|
|
33
33
|
History: Історія
|
34
34
|
Job: Задача
|
35
35
|
Jobs: Задачі
|
36
|
-
Kill:
|
37
|
-
KillAll:
|
36
|
+
Kill: Зупинити
|
37
|
+
KillAll: Зупинити все
|
38
38
|
LastRetry: Остання спроба
|
39
39
|
Latency: Затримка
|
40
40
|
LivePoll: Постійне опитування
|
@@ -42,7 +42,7 @@ uk:
|
|
42
42
|
Name: Назва
|
43
43
|
Namespace: Простір імен
|
44
44
|
NextRetry: Наступна спроба
|
45
|
-
NoDeadJobsFound:
|
45
|
+
NoDeadJobsFound: Зупинених задач не знайдено
|
46
46
|
NoRetriesFound: Спроб не знайдено
|
47
47
|
NoScheduledFound: Запланованих задач не знайдено
|
48
48
|
NotYetEnqueued: Ще не в черзі
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 8.0.
|
4
|
+
version: 8.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Perham
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- lib/sidekiq/job_retry.rb
|
123
123
|
- lib/sidekiq/job_util.rb
|
124
124
|
- lib/sidekiq/launcher.rb
|
125
|
+
- lib/sidekiq/loader.rb
|
125
126
|
- lib/sidekiq/logger.rb
|
126
127
|
- lib/sidekiq/manager.rb
|
127
128
|
- lib/sidekiq/metrics/query.rb
|