sidekiq 7.3.0 → 7.3.9
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 +81 -0
- data/bin/sidekiqload +21 -12
- 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 +62 -33
- data/lib/sidekiq/capsule.rb +5 -3
- data/lib/sidekiq/cli.rb +1 -1
- data/lib/sidekiq/client.rb +21 -1
- data/lib/sidekiq/component.rb +22 -0
- data/lib/sidekiq/config.rb +22 -2
- data/lib/sidekiq/deploy.rb +2 -0
- data/lib/sidekiq/embedded.rb +2 -0
- data/lib/sidekiq/iterable_job.rb +2 -0
- data/lib/sidekiq/job/interrupt_handler.rb +2 -0
- data/lib/sidekiq/job/iterable/active_record_enumerator.rb +3 -3
- data/lib/sidekiq/job/iterable.rb +69 -6
- data/lib/sidekiq/job_logger.rb +11 -23
- data/lib/sidekiq/job_util.rb +2 -0
- data/lib/sidekiq/launcher.rb +1 -1
- data/lib/sidekiq/metrics/query.rb +2 -0
- data/lib/sidekiq/metrics/shared.rb +15 -4
- data/lib/sidekiq/metrics/tracking.rb +13 -5
- data/lib/sidekiq/middleware/current_attributes.rb +19 -2
- data/lib/sidekiq/middleware/modules.rb +2 -0
- data/lib/sidekiq/monitor.rb +2 -1
- data/lib/sidekiq/paginator.rb +6 -0
- data/lib/sidekiq/processor.rb +10 -10
- data/lib/sidekiq/rails.rb +12 -0
- data/lib/sidekiq/redis_connection.rb +8 -1
- data/lib/sidekiq/ring_buffer.rb +2 -0
- data/lib/sidekiq/systemd.rb +2 -0
- data/lib/sidekiq/testing.rb +5 -5
- data/lib/sidekiq/version.rb +5 -1
- data/lib/sidekiq/web/action.rb +20 -4
- data/lib/sidekiq/web/application.rb +36 -79
- data/lib/sidekiq/web/helpers.rb +11 -10
- data/lib/sidekiq/web/router.rb +5 -2
- data/lib/sidekiq/web.rb +8 -1
- data/lib/sidekiq.rb +4 -3
- data/sidekiq.gemspec +1 -1
- data/web/assets/javascripts/dashboard-charts.js +2 -0
- data/web/assets/javascripts/dashboard.js +6 -0
- data/web/assets/stylesheets/application.css +9 -8
- data/web/locales/en.yml +3 -1
- data/web/locales/fr.yml +0 -1
- data/web/locales/gd.yml +0 -1
- data/web/locales/it.yml +32 -1
- data/web/locales/ja.yml +0 -1
- data/web/locales/pt-br.yml +1 -2
- data/web/locales/tr.yml +1 -2
- data/web/locales/uk.yml +24 -1
- data/web/locales/zh-cn.yml +0 -1
- data/web/locales/zh-tw.yml +0 -1
- data/web/views/_footer.erb +1 -2
- data/web/views/dashboard.erb +4 -1
- data/web/views/filtering.erb +1 -2
- data/web/views/metrics.erb +3 -4
- data/web/views/morgue.erb +2 -2
- data/web/views/queue.erb +1 -1
- metadata +10 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dccc402e8f4e309a47a2adb62418fa29989012e8c94f34aa11200b098dc375f2
|
4
|
+
data.tar.gz: 71b64a582d5971b045d60bae38dc26da265b60ff9a099ca3b2f9c7df9035e805
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9148b613a222ca9617ceebe25bb04a5d086edacdafad4a426b6232662d3b583db462dc5e0491297f7859037c5166bcb541bddcd3949f6d3b5a1c2e3fc572b65
|
7
|
+
data.tar.gz: 93a797cefd1a68adb236c7538c28571467c328d6965af0bc5ce505a1391d6f5b6e2ae2c87b42110e837dcfa8d788aff55309806bbb1bcd181e205c3bc66adc29
|
data/Changes.md
CHANGED
@@ -2,6 +2,87 @@
|
|
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
|
+
7.3.9
|
6
|
+
----------
|
7
|
+
|
8
|
+
- Only require activejob if necessary [#6584]
|
9
|
+
- Fix iterable job cancellation [#6589]
|
10
|
+
- Web UI accessibility improvements [#6604]
|
11
|
+
|
12
|
+
7.3.8
|
13
|
+
----------
|
14
|
+
|
15
|
+
- Fix dead tag links [#6554]
|
16
|
+
- Massive Web UI performance improvement, some pages up to 15x faster [#6555]
|
17
|
+
|
18
|
+
7.3.7
|
19
|
+
----------
|
20
|
+
|
21
|
+
- Backport `Sidekiq::Web.configure` for compatibility with 8.0 [#6532]
|
22
|
+
- Backport `url_params(key)` and `route_params(key)` for compatibility with 8.0 [#6532]
|
23
|
+
- Various fixes for UI filtering [#6508]
|
24
|
+
- Tune `inspect` for internal S::Components to keep size managable [#6553]
|
25
|
+
|
26
|
+
7.3.6
|
27
|
+
----------
|
28
|
+
|
29
|
+
- Forward compatibility fixes for Ruby 3.4
|
30
|
+
- Filtering in the Web UI now works via GET so you can bookmark a filtered view. [#6497]
|
31
|
+
|
32
|
+
7.3.5
|
33
|
+
----------
|
34
|
+
|
35
|
+
- Reimplement `retry_all` and `kill_all` API methods to use ZPOPMIN,
|
36
|
+
approximately 30-60% faster. [#6481]
|
37
|
+
- Add preload testing binary at `examples/testing/sidekiq_boot` to verify your Rails app boots correctly with Sidekiq Enterprise's app preloading.
|
38
|
+
- Fix circular require with ActiveJob adapter [#6477]
|
39
|
+
- Fix potential race condition leading to incorrect serialized values for CurrentAttributes [#6475]
|
40
|
+
- Restore missing elapsed time when default job logging is disabled
|
41
|
+
|
42
|
+
7.3.4
|
43
|
+
----------
|
44
|
+
|
45
|
+
- Fix FrozenError when starting Sidekiq [#6470]
|
46
|
+
|
47
|
+
7.3.3
|
48
|
+
----------
|
49
|
+
|
50
|
+
- Freeze global configuration once boot is complete, to avoid configuration race conditions [#6466, #6465]
|
51
|
+
- Sidekiq now warns if a job iteration takes longer than the `-t` timeout setting (defaults to 25 seconds)
|
52
|
+
- Iteration callbacks now have easy access to job arguments via the `arguments` method:
|
53
|
+
```ruby
|
54
|
+
def on_stop
|
55
|
+
p arguments # => `[123, "string", {"key" => "value"}]`
|
56
|
+
id, str, hash = arguments
|
57
|
+
end
|
58
|
+
```
|
59
|
+
- Iterable jobs can be cancelled via `Sidekiq::Client#cancel!`:
|
60
|
+
```ruby
|
61
|
+
c = Sidekiq::Client.new
|
62
|
+
jid = c.push("class" => SomeJob, "args" => [123])
|
63
|
+
c.cancel!(jid) # => true
|
64
|
+
```
|
65
|
+
- Take over support for ActiveJob's `:sidekiq` adapter [#6430, fatkodima]
|
66
|
+
- Ensure CurrentAttributes are in scope when creating batch callbacks [#6455]
|
67
|
+
- Add `Sidekiq.gem_version` API.
|
68
|
+
- Update Ukranian translations
|
69
|
+
|
70
|
+
7.3.2
|
71
|
+
----------
|
72
|
+
|
73
|
+
- Adjust ActiveRecord batch iteration to restart an interrupted batch from the beginning.
|
74
|
+
Each batch should be processed as a single transaction in order to be idempotent. [#6405]
|
75
|
+
- Fix typo in Sidekiq::DeadSet#kill [#6397]
|
76
|
+
- Fix CSS issue with bottom bar in Web UI [#6414]
|
77
|
+
|
78
|
+
7.3.1
|
79
|
+
----------
|
80
|
+
|
81
|
+
- Don't count job interruptions as failures in metrics [#6386]
|
82
|
+
- Add frozen string literal to a number of .rb files.
|
83
|
+
- Fix frozen string error with style_tag and script_tag [#6371]
|
84
|
+
- Fix an error on Ruby 2.7 because of usage of `Hash#except` [#6376]
|
85
|
+
|
5
86
|
7.3.0
|
6
87
|
----------
|
7
88
|
|
data/bin/sidekiqload
CHANGED
@@ -50,7 +50,7 @@ if ENV["AJ"]
|
|
50
50
|
ActiveJob::Base.logger.level = Logger::WARN
|
51
51
|
|
52
52
|
class LoadJob < ActiveJob::Base
|
53
|
-
def perform(idx, ts = nil)
|
53
|
+
def perform(string, idx, hash, ts = nil)
|
54
54
|
puts(Time.now.to_f - ts) if !ts.nil?
|
55
55
|
end
|
56
56
|
end
|
@@ -58,12 +58,21 @@ end
|
|
58
58
|
|
59
59
|
class LoadWorker
|
60
60
|
include Sidekiq::Job
|
61
|
+
$count = 0
|
62
|
+
$lock = Mutex.new
|
63
|
+
|
61
64
|
sidekiq_options retry: 1
|
62
65
|
sidekiq_retry_in do |x|
|
63
66
|
1
|
64
67
|
end
|
65
68
|
|
66
|
-
def perform(idx, ts = nil)
|
69
|
+
def perform(string, idx, hash, ts = nil)
|
70
|
+
$lock.synchronize do
|
71
|
+
$count += 1
|
72
|
+
if $count % 100_000 == 0
|
73
|
+
logger.warn("#{Time.now} Done #{$count}")
|
74
|
+
end
|
75
|
+
end
|
67
76
|
puts(Time.now.to_f - ts) if !ts.nil?
|
68
77
|
# raise idx.to_s if idx % 100 == 1
|
69
78
|
end
|
@@ -133,13 +142,13 @@ class Loader
|
|
133
142
|
start = Time.now
|
134
143
|
if ENV["AJ"]
|
135
144
|
@iter.times do
|
136
|
-
@count.times do |idx|
|
137
|
-
LoadJob.
|
138
|
-
end
|
145
|
+
ActiveJob.perform_all_later(@count.times.map do |idx|
|
146
|
+
LoadJob.new("mike", idx, {mike: "bob"})
|
147
|
+
end)
|
139
148
|
end
|
140
149
|
else
|
141
150
|
@iter.times do
|
142
|
-
arr = Array.new(@count) { |idx| [idx] }
|
151
|
+
arr = Array.new(@count) { |idx| ["string", idx, {"mike" => "bob"}] }
|
143
152
|
Sidekiq::Client.push_bulk("class" => LoadWorker, "args" => arr)
|
144
153
|
end
|
145
154
|
end
|
@@ -163,13 +172,13 @@ class Loader
|
|
163
172
|
Sidekiq.logger.error("Now here's the latency for three jobs")
|
164
173
|
|
165
174
|
if ENV["AJ"]
|
166
|
-
LoadJob.perform_later(1, Time.now.to_f)
|
167
|
-
LoadJob.perform_later(2, Time.now.to_f)
|
168
|
-
LoadJob.perform_later(3, Time.now.to_f)
|
175
|
+
LoadJob.perform_later("", 1, {}, Time.now.to_f)
|
176
|
+
LoadJob.perform_later("", 2, {}, Time.now.to_f)
|
177
|
+
LoadJob.perform_later("", 3, {}, Time.now.to_f)
|
169
178
|
else
|
170
|
-
LoadWorker.perform_async(1, Time.now.to_f)
|
171
|
-
LoadWorker.perform_async(2, Time.now.to_f)
|
172
|
-
LoadWorker.perform_async(3, Time.now.to_f)
|
179
|
+
LoadWorker.perform_async("", 1, {}, Time.now.to_f)
|
180
|
+
LoadWorker.perform_async("", 2, {}, Time.now.to_f)
|
181
|
+
LoadWorker.perform_async("", 3, {}, Time.now.to_f)
|
173
182
|
end
|
174
183
|
|
175
184
|
sleep 0.1
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveJob
|
4
|
+
module QueueAdapters
|
5
|
+
# Explicitly remove the implementation existing in older rails'.
|
6
|
+
remove_const(:SidekiqAdapter) if const_defined?(:SidekiqAdapter)
|
7
|
+
|
8
|
+
# Sidekiq adapter for Active Job
|
9
|
+
#
|
10
|
+
# To use Sidekiq set the queue_adapter config to +:sidekiq+.
|
11
|
+
#
|
12
|
+
# Rails.application.config.active_job.queue_adapter = :sidekiq
|
13
|
+
class SidekiqAdapter
|
14
|
+
# Defines whether enqueuing should happen implicitly to after commit when called
|
15
|
+
# from inside a transaction.
|
16
|
+
# @api private
|
17
|
+
def enqueue_after_transaction_commit?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def enqueue(job)
|
23
|
+
job.provider_job_id = JobWrapper.set(
|
24
|
+
wrapped: job.class,
|
25
|
+
queue: job.queue_name
|
26
|
+
).perform_async(job.serialize)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @api private
|
30
|
+
def enqueue_at(job, timestamp)
|
31
|
+
job.provider_job_id = JobWrapper.set(
|
32
|
+
wrapped: job.class,
|
33
|
+
queue: job.queue_name
|
34
|
+
).perform_at(timestamp, job.serialize)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @api private
|
38
|
+
def enqueue_all(jobs)
|
39
|
+
enqueued_count = 0
|
40
|
+
jobs.group_by(&:class).each do |job_class, same_class_jobs|
|
41
|
+
same_class_jobs.group_by(&:queue_name).each do |queue, same_class_and_queue_jobs|
|
42
|
+
immediate_jobs, scheduled_jobs = same_class_and_queue_jobs.partition { |job| job.scheduled_at.nil? }
|
43
|
+
|
44
|
+
if immediate_jobs.any?
|
45
|
+
jids = Sidekiq::Client.push_bulk(
|
46
|
+
"class" => JobWrapper,
|
47
|
+
"wrapped" => job_class,
|
48
|
+
"queue" => queue,
|
49
|
+
"args" => immediate_jobs.map { |job| [job.serialize] }
|
50
|
+
)
|
51
|
+
enqueued_count += jids.compact.size
|
52
|
+
end
|
53
|
+
|
54
|
+
if scheduled_jobs.any?
|
55
|
+
jids = Sidekiq::Client.push_bulk(
|
56
|
+
"class" => JobWrapper,
|
57
|
+
"wrapped" => job_class,
|
58
|
+
"queue" => queue,
|
59
|
+
"args" => scheduled_jobs.map { |job| [job.serialize] },
|
60
|
+
"at" => scheduled_jobs.map { |job| job.scheduled_at&.to_f }
|
61
|
+
)
|
62
|
+
enqueued_count += jids.compact.size
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
enqueued_count
|
67
|
+
end
|
68
|
+
|
69
|
+
# Defines a class alias for backwards compatibility with enqueued Active Job jobs.
|
70
|
+
# @api private
|
71
|
+
class JobWrapper < Sidekiq::ActiveJob::Wrapper
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/sidekiq/api.rb
CHANGED
@@ -373,7 +373,7 @@ module Sidekiq
|
|
373
373
|
def display_class
|
374
374
|
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
375
375
|
@klass ||= self["display_class"] || begin
|
376
|
-
if klass == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
376
|
+
if klass == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper" || klass == "Sidekiq::ActiveJob::Wrapper"
|
377
377
|
job_class = @item["wrapped"] || args[0]
|
378
378
|
if job_class == "ActionMailer::DeliveryJob" || job_class == "ActionMailer::MailDeliveryJob"
|
379
379
|
# MailerClass#mailer_method
|
@@ -389,7 +389,7 @@ module Sidekiq
|
|
389
389
|
|
390
390
|
def display_args
|
391
391
|
# Unwrap known wrappers so they show up in a human-friendly manner in the Web UI
|
392
|
-
@display_args ||= if klass == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"
|
392
|
+
@display_args ||= if klass == "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper" || klass == "Sidekiq::ActiveJob::Wrapper"
|
393
393
|
job_args = self["wrapped"] ? deserialize_argument(args[0]["arguments"]) : []
|
394
394
|
if (self["wrapped"] || args[0]) == "ActionMailer::DeliveryJob"
|
395
395
|
# remove MailerClass, mailer_method and 'deliver_now'
|
@@ -668,6 +668,41 @@ module Sidekiq
|
|
668
668
|
end
|
669
669
|
end
|
670
670
|
|
671
|
+
def pop_each
|
672
|
+
Sidekiq.redis do |c|
|
673
|
+
size.times do
|
674
|
+
data, score = c.zpopmin(name, 1)&.first
|
675
|
+
break unless data
|
676
|
+
yield data, score
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
def retry_all
|
682
|
+
c = Sidekiq::Client.new
|
683
|
+
pop_each do |msg, _|
|
684
|
+
job = Sidekiq.load_json(msg)
|
685
|
+
# Manual retries should not count against the retry limit.
|
686
|
+
job["retry_count"] -= 1 if job["retry_count"]
|
687
|
+
c.push(job)
|
688
|
+
end
|
689
|
+
end
|
690
|
+
|
691
|
+
# Move all jobs from this Set to the Dead Set.
|
692
|
+
# See DeadSet#kill
|
693
|
+
def kill_all(notify_failure: false, ex: nil)
|
694
|
+
ds = DeadSet.new
|
695
|
+
opts = {notify_failure: notify_failure, ex: ex, trim: false}
|
696
|
+
|
697
|
+
begin
|
698
|
+
pop_each do |msg, _|
|
699
|
+
ds.kill(msg, opts)
|
700
|
+
end
|
701
|
+
ensure
|
702
|
+
ds.trim
|
703
|
+
end
|
704
|
+
end
|
705
|
+
|
671
706
|
def each
|
672
707
|
initial_size = @_size
|
673
708
|
offset_size = 0
|
@@ -765,10 +800,6 @@ module Sidekiq
|
|
765
800
|
|
766
801
|
##
|
767
802
|
# The set of scheduled jobs within Sidekiq.
|
768
|
-
# Based on this, you can search/filter for jobs. Here's an
|
769
|
-
# example where I'm selecting jobs based on some complex logic
|
770
|
-
# and deleting them from the scheduled set.
|
771
|
-
#
|
772
803
|
# See the API wiki page for usage notes and examples.
|
773
804
|
#
|
774
805
|
class ScheduledSet < JobSet
|
@@ -779,26 +810,12 @@ module Sidekiq
|
|
779
810
|
|
780
811
|
##
|
781
812
|
# The set of retries within Sidekiq.
|
782
|
-
# Based on this, you can search/filter for jobs. Here's an
|
783
|
-
# example where I'm selecting all jobs of a certain type
|
784
|
-
# and deleting them from the retry queue.
|
785
|
-
#
|
786
813
|
# See the API wiki page for usage notes and examples.
|
787
814
|
#
|
788
815
|
class RetrySet < JobSet
|
789
816
|
def initialize
|
790
817
|
super("retry")
|
791
818
|
end
|
792
|
-
|
793
|
-
# Enqueues all jobs pending within the retry set.
|
794
|
-
def retry_all
|
795
|
-
each(&:retry) while size > 0
|
796
|
-
end
|
797
|
-
|
798
|
-
# Kills all jobs pending within the retry set.
|
799
|
-
def kill_all
|
800
|
-
each(&:kill) while size > 0
|
801
|
-
end
|
802
819
|
end
|
803
820
|
|
804
821
|
##
|
@@ -811,33 +828,45 @@ module Sidekiq
|
|
811
828
|
super("dead")
|
812
829
|
end
|
813
830
|
|
831
|
+
# Trim dead jobs which are over our storage limits
|
832
|
+
def trim
|
833
|
+
hash = Sidekiq.default_configuration
|
834
|
+
now = Time.now.to_f
|
835
|
+
Sidekiq.redis do |conn|
|
836
|
+
conn.multi do |transaction|
|
837
|
+
transaction.zremrangebyscore(name, "-inf", now - hash[:dead_timeout_in_seconds])
|
838
|
+
transaction.zremrangebyrank(name, 0, - hash[:dead_max_jobs])
|
839
|
+
end
|
840
|
+
end
|
841
|
+
end
|
842
|
+
|
814
843
|
# Add the given job to the Dead set.
|
815
844
|
# @param message [String] the job data as JSON
|
845
|
+
# @option opts [Boolean] :notify_failure (true) Whether death handlers should be called
|
846
|
+
# @option opts [Boolean] :trim (true) Whether Sidekiq should trim the structure to keep it within configuration
|
847
|
+
# @option opts [Exception] :ex (RuntimeError) An exception to pass to the death handlers
|
816
848
|
def kill(message, opts = {})
|
817
849
|
now = Time.now.to_f
|
818
850
|
Sidekiq.redis do |conn|
|
819
|
-
conn.
|
820
|
-
transaction.zadd(name, now.to_s, message)
|
821
|
-
transaction.zremrangebyscore(name, "-inf", now - Sidekiq::Config::DEFAULTS[:dead_timeout_in_seconds])
|
822
|
-
transaction.zremrangebyrank(name, 0, - Sidekiq::Config::DEFAULTS[:dead_max_jobs])
|
823
|
-
end
|
851
|
+
conn.zadd(name, now.to_s, message)
|
824
852
|
end
|
825
853
|
|
854
|
+
trim if opts[:trim] != false
|
855
|
+
|
826
856
|
if opts[:notify_failure] != false
|
827
857
|
job = Sidekiq.load_json(message)
|
828
|
-
|
829
|
-
|
858
|
+
if opts[:ex]
|
859
|
+
ex = opts[:ex]
|
860
|
+
else
|
861
|
+
ex = RuntimeError.new("Job killed by API")
|
862
|
+
ex.set_backtrace(caller)
|
863
|
+
end
|
830
864
|
Sidekiq.default_configuration.death_handlers.each do |handle|
|
831
|
-
handle.call(job,
|
865
|
+
handle.call(job, ex)
|
832
866
|
end
|
833
867
|
end
|
834
868
|
true
|
835
869
|
end
|
836
|
-
|
837
|
-
# Enqueue all dead jobs
|
838
|
-
def retry_all
|
839
|
-
each(&:retry) while size > 0
|
840
|
-
end
|
841
870
|
end
|
842
871
|
|
843
872
|
##
|
data/lib/sidekiq/capsule.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "sidekiq/component"
|
2
4
|
|
3
5
|
module Sidekiq
|
@@ -38,9 +40,9 @@ module Sidekiq
|
|
38
40
|
|
39
41
|
def fetcher
|
40
42
|
@fetcher ||= begin
|
41
|
-
|
42
|
-
|
43
|
-
|
43
|
+
instance = (config[:fetch_class] || Sidekiq::BasicFetch).new(self)
|
44
|
+
instance.setup(config[:fetch_setup]) if instance.respond_to?(:setup)
|
45
|
+
instance
|
44
46
|
end
|
45
47
|
end
|
46
48
|
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -101,7 +101,7 @@ module Sidekiq # :nodoc:
|
|
101
101
|
# Touch middleware so it isn't lazy loaded by multiple threads, #3043
|
102
102
|
@config.server_middleware
|
103
103
|
|
104
|
-
::Process.warmup if warmup && ::Process.respond_to?(:warmup)
|
104
|
+
::Process.warmup if warmup && ::Process.respond_to?(:warmup) && ENV["RUBY_DISABLE_WARMUP"] != "1"
|
105
105
|
|
106
106
|
# Before this point, the process is initializing with just the main thread.
|
107
107
|
# Starting here the process will now have multiple threads running.
|
data/lib/sidekiq/client.rb
CHANGED
@@ -58,6 +58,23 @@ module Sidekiq
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
# Cancel the IterableJob with the given JID.
|
62
|
+
# **NB: Cancellation is asynchronous.** Iteration checks every
|
63
|
+
# five seconds so this will not immediately stop the given job.
|
64
|
+
def cancel!(jid)
|
65
|
+
key = "it-#{jid}"
|
66
|
+
_, result, _ = Sidekiq.redis do |c|
|
67
|
+
c.pipelined do |p|
|
68
|
+
p.hsetnx(key, "cancelled", Time.now.to_i)
|
69
|
+
p.hget(key, "cancelled")
|
70
|
+
p.expire(key, Sidekiq::Job::Iterable::STATE_TTL)
|
71
|
+
# TODO When Redis 7.2 is required
|
72
|
+
# p.expire(key, Sidekiq::Job::Iterable::STATE_TTL, "nx")
|
73
|
+
end
|
74
|
+
end
|
75
|
+
result.to_i
|
76
|
+
end
|
77
|
+
|
61
78
|
##
|
62
79
|
# The main method used to push a job to Redis. Accepts a number of options:
|
63
80
|
#
|
@@ -251,7 +268,10 @@ module Sidekiq
|
|
251
268
|
at = hash["at"].to_s
|
252
269
|
# ActiveJob sets this but the job has not been enqueued yet
|
253
270
|
hash.delete("enqueued_at")
|
254
|
-
|
271
|
+
# TODO: Use hash.except("at") when support for Ruby 2.7 is dropped
|
272
|
+
hash = hash.dup
|
273
|
+
hash.delete("at")
|
274
|
+
[at, Sidekiq.dump_json(hash)]
|
255
275
|
})
|
256
276
|
else
|
257
277
|
queue = payloads.first["queue"]
|
data/lib/sidekiq/component.rb
CHANGED
@@ -64,5 +64,27 @@ module Sidekiq
|
|
64
64
|
end
|
65
65
|
arr.clear if oneshot # once we've fired an event, we never fire it again
|
66
66
|
end
|
67
|
+
|
68
|
+
# When you have a large tree of components, the `inspect` output
|
69
|
+
# can get out of hand, especially with lots of Sidekiq::Config
|
70
|
+
# references everywhere. We avoid calling `inspect` on more complex
|
71
|
+
# state and use `to_s` instead to keep output manageable, #6553
|
72
|
+
def inspect
|
73
|
+
"#<#{self.class.name} #{
|
74
|
+
instance_variables.map do |name|
|
75
|
+
value = instance_variable_get(name)
|
76
|
+
case value
|
77
|
+
when Proc
|
78
|
+
"#{name}=#{value}"
|
79
|
+
when Sidekiq::Config
|
80
|
+
"#{name}=#{value}"
|
81
|
+
when Sidekiq::Component
|
82
|
+
"#{name}=#{value}"
|
83
|
+
else
|
84
|
+
"#{name}=#{value.inspect}"
|
85
|
+
end
|
86
|
+
end.join(", ")
|
87
|
+
}>"
|
88
|
+
end
|
67
89
|
end
|
68
90
|
end
|
data/lib/sidekiq/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "forwardable"
|
2
4
|
|
3
5
|
require "set"
|
@@ -59,6 +61,12 @@ module Sidekiq
|
|
59
61
|
def_delegators :@options, :[], :[]=, :fetch, :key?, :has_key?, :merge!, :dig
|
60
62
|
attr_reader :capsules
|
61
63
|
|
64
|
+
def inspect
|
65
|
+
"#<#{self.class.name} @options=#{
|
66
|
+
@options.except(:lifecycle_events, :reloader, :death_handlers, :error_handlers).inspect
|
67
|
+
}>"
|
68
|
+
end
|
69
|
+
|
62
70
|
def to_json(*)
|
63
71
|
Sidekiq.dump_json(@options)
|
64
72
|
end
|
@@ -183,7 +191,13 @@ module Sidekiq
|
|
183
191
|
|
184
192
|
# register global singletons which can be accessed elsewhere
|
185
193
|
def register(name, instance)
|
186
|
-
|
194
|
+
# logger.debug("register[#{name}] = #{instance}")
|
195
|
+
# Sidekiq Enterprise lazy registers a few services so we
|
196
|
+
# can't lock down this hash completely.
|
197
|
+
hash = @directory.dup
|
198
|
+
hash[name] = instance
|
199
|
+
@directory = hash.freeze
|
200
|
+
instance
|
187
201
|
end
|
188
202
|
|
189
203
|
# find a singleton
|
@@ -191,10 +205,16 @@ module Sidekiq
|
|
191
205
|
# JNDI is just a fancy name for a hash lookup
|
192
206
|
@directory.fetch(name) do |key|
|
193
207
|
return nil unless default_class
|
194
|
-
|
208
|
+
register(key, default_class.new(self))
|
195
209
|
end
|
196
210
|
end
|
197
211
|
|
212
|
+
def freeze!
|
213
|
+
@directory.freeze
|
214
|
+
@options.freeze
|
215
|
+
true
|
216
|
+
end
|
217
|
+
|
198
218
|
##
|
199
219
|
# Death handlers are called when all retries for a job have been exhausted and
|
200
220
|
# the job dies. It's the notification to your application
|
data/lib/sidekiq/deploy.rb
CHANGED
data/lib/sidekiq/embedded.rb
CHANGED
data/lib/sidekiq/iterable_job.rb
CHANGED
@@ -22,7 +22,7 @@ module Sidekiq
|
|
22
22
|
def batches
|
23
23
|
Enumerator.new(-> { @relation.count }) do |yielder|
|
24
24
|
@relation.find_in_batches(**@options, start: @cursor) do |batch|
|
25
|
-
yielder.yield(batch, batch.
|
25
|
+
yielder.yield(batch, batch.first.id)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -35,8 +35,8 @@ module Sidekiq
|
|
35
35
|
options[:of] ||= options.delete(:batch_size)
|
36
36
|
|
37
37
|
@relation.in_batches(**options, start: @cursor) do |relation|
|
38
|
-
|
39
|
-
yielder.yield(relation,
|
38
|
+
first_record = relation.first
|
39
|
+
yielder.yield(relation, first_record.id)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|