sidekiq-throttled 1.5.0 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sidekiq/throttled/job.rb +0 -9
- data/lib/sidekiq/throttled/strategy.rb +49 -25
- data/lib/sidekiq/throttled/version.rb +1 -1
- data/lib/sidekiq/throttled.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a601fd050b147fd24ab88416d29273f0cca950c7e540c6303e1c0bb9c47f66d
|
4
|
+
data.tar.gz: 72ebc4a88c60c09faa9922c4f305fbe4374a90ebcafa62f149b83cbae6a356a6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a41505e78b80af968f4aa3ab5076298d8acb62ab4b79046bbb8ff3d7cdb83d456546d066c3c431033418d5754b300cb16c30443b4f66bf82c30b14c5043b3ab4
|
7
|
+
data.tar.gz: 95b3c4839f01711aa6ff3fca8f390ab49981f7e7cf1cf3cd9c289276f945943ada4a3ec9adf96413cf1435f58fe9ea8c08f2b31fc3133e4fbbfca646d0c677b0
|
@@ -24,8 +24,6 @@ module Sidekiq
|
|
24
24
|
#
|
25
25
|
# @see ClassMethods
|
26
26
|
module Job
|
27
|
-
VALID_VALUES_FOR_REQUEUE_WITH = %i[enqueue schedule].freeze
|
28
|
-
|
29
27
|
# Extends worker class with {ClassMethods}.
|
30
28
|
#
|
31
29
|
# @note Using `included` hook with extending worker with {ClassMethods}
|
@@ -91,13 +89,6 @@ module Sidekiq
|
|
91
89
|
# @see Registry.add
|
92
90
|
# @return [void]
|
93
91
|
def sidekiq_throttle(**kwargs)
|
94
|
-
requeue_options = Throttled.config.default_requeue_options.merge(kwargs.delete(:requeue) || {})
|
95
|
-
unless VALID_VALUES_FOR_REQUEUE_WITH.include?(requeue_options[:with])
|
96
|
-
raise ArgumentError, "requeue: #{requeue_options[:with]} is not a valid value for :with"
|
97
|
-
end
|
98
|
-
|
99
|
-
self.sidekiq_throttled_requeue_options = requeue_options
|
100
|
-
|
101
92
|
Registry.add(self, **kwargs)
|
102
93
|
end
|
103
94
|
|
@@ -11,7 +11,11 @@ module Sidekiq
|
|
11
11
|
# Meta-strategy that couples {Concurrency} and {Threshold} strategies.
|
12
12
|
#
|
13
13
|
# @private
|
14
|
-
class Strategy
|
14
|
+
class Strategy # rubocop:disable Metrics/ClassLength
|
15
|
+
# :enqueue means put the job back at the end of the queue immediately
|
16
|
+
# :schedule means schedule enqueueing the job for a later time when we expect to have capacity
|
17
|
+
VALID_VALUES_FOR_REQUEUE_WITH = %i[enqueue schedule].freeze
|
18
|
+
|
15
19
|
# @!attribute [r] concurrency
|
16
20
|
# @return [Strategy::Concurrency, nil]
|
17
21
|
attr_reader :concurrency
|
@@ -24,6 +28,10 @@ module Sidekiq
|
|
24
28
|
# @return [Proc, nil]
|
25
29
|
attr_reader :observer
|
26
30
|
|
31
|
+
# @!attribute [r] requeue_options
|
32
|
+
# @return [Hash, nil]
|
33
|
+
attr_reader :requeue_options
|
34
|
+
|
27
35
|
# @param [#to_s] name
|
28
36
|
# @param [Hash] concurrency Concurrency options.
|
29
37
|
# See keyword args of {Strategy::Concurrency#initialize} for details.
|
@@ -31,7 +39,8 @@ module Sidekiq
|
|
31
39
|
# See keyword args of {Strategy::Threshold#initialize} for details.
|
32
40
|
# @param [#call] key_suffix Dynamic key suffix generator.
|
33
41
|
# @param [#call] observer Process called after throttled.
|
34
|
-
|
42
|
+
# @param [#call] requeue What to do with jobs that are throttled.
|
43
|
+
def initialize(name, concurrency: nil, threshold: nil, key_suffix: nil, observer: nil, requeue: nil) # rubocop:disable Metrics/MethodLength, Metrics/ParameterLists
|
35
44
|
@observer = observer
|
36
45
|
|
37
46
|
@concurrency = StrategyCollection.new(concurrency,
|
@@ -44,7 +53,9 @@ module Sidekiq
|
|
44
53
|
name: name,
|
45
54
|
key_suffix: key_suffix)
|
46
55
|
|
47
|
-
|
56
|
+
@requeue_options = Throttled.config.default_requeue_options.merge(requeue || {})
|
57
|
+
|
58
|
+
validate!
|
48
59
|
end
|
49
60
|
|
50
61
|
# @return [Boolean] whenever strategy has dynamic config
|
@@ -72,26 +83,30 @@ module Sidekiq
|
|
72
83
|
false
|
73
84
|
end
|
74
85
|
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
# @
|
81
|
-
|
86
|
+
# @return [Proc, Symbol] How to requeue the throttled job
|
87
|
+
def requeue_with
|
88
|
+
requeue_options[:with]
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [String, nil] Name of the queue to re-queue the job to.
|
92
|
+
def requeue_to
|
93
|
+
requeue_options[:to]
|
94
|
+
end
|
95
|
+
|
96
|
+
# Return throttled job to be executed later. Implementation depends on the strategy's `requeue` options.
|
82
97
|
# @return [void]
|
83
|
-
def requeue_throttled(work
|
84
|
-
# Resolve :with and :to
|
98
|
+
def requeue_throttled(work) # rubocop:disable Metrics/MethodLength
|
99
|
+
# Resolve :with and :to options, calling them if they are Procs
|
85
100
|
job_args = JSON.parse(work.job)["args"]
|
86
|
-
|
87
|
-
target_queue = calc_target_queue(work
|
101
|
+
with = requeue_with.respond_to?(:call) ? requeue_with.call(*job_args) : requeue_with
|
102
|
+
target_queue = calc_target_queue(work)
|
88
103
|
|
89
|
-
case
|
104
|
+
case with
|
90
105
|
when :enqueue
|
91
106
|
re_enqueue_throttled(work, target_queue)
|
92
107
|
when :schedule
|
93
108
|
# Find out when we will next be able to execute this job, and reschedule for then.
|
94
|
-
reschedule_throttled(work,
|
109
|
+
reschedule_throttled(work, target_queue)
|
95
110
|
else
|
96
111
|
raise "unrecognized :with option #{with}"
|
97
112
|
end
|
@@ -112,14 +127,23 @@ module Sidekiq
|
|
112
127
|
|
113
128
|
private
|
114
129
|
|
115
|
-
def
|
116
|
-
|
130
|
+
def validate!
|
131
|
+
unless VALID_VALUES_FOR_REQUEUE_WITH.include?(@requeue_options[:with]) ||
|
132
|
+
@requeue_options[:with].respond_to?(:call)
|
133
|
+
raise ArgumentError, "requeue: #{@requeue_options[:with]} is not a valid value for :with"
|
134
|
+
end
|
135
|
+
|
136
|
+
raise ArgumentError, "Neither :concurrency nor :threshold given" unless @concurrency.any? || @threshold.any?
|
137
|
+
end
|
138
|
+
|
139
|
+
def calc_target_queue(work) # rubocop:disable Metrics/MethodLength
|
140
|
+
target = case requeue_to
|
117
141
|
when Proc, Method
|
118
|
-
|
142
|
+
requeue_to.call(*JSON.parse(work.job)["args"])
|
119
143
|
when NilClass
|
120
144
|
work.queue
|
121
145
|
when String, Symbol
|
122
|
-
|
146
|
+
requeue_to.to_s
|
123
147
|
else
|
124
148
|
raise ArgumentError, "Invalid argument for `to`"
|
125
149
|
end
|
@@ -130,21 +154,21 @@ module Sidekiq
|
|
130
154
|
end
|
131
155
|
|
132
156
|
# Push the job back to the head of the queue.
|
133
|
-
def re_enqueue_throttled(work,
|
157
|
+
def re_enqueue_throttled(work, target_queue)
|
134
158
|
case work.class.name
|
135
159
|
when "Sidekiq::Pro::SuperFetch::UnitOfWork"
|
136
160
|
# Calls SuperFetch UnitOfWork's requeue to remove the job from the
|
137
161
|
# temporary queue and push job back to the head of the target queue, so that
|
138
162
|
# the job won't be tried immediately after it was requeued (in most cases).
|
139
|
-
work.queue =
|
163
|
+
work.queue = target_queue if target_queue
|
140
164
|
work.requeue
|
141
165
|
else
|
142
166
|
# This is the same operation Sidekiq performs upon `Sidekiq::Worker.perform_async` call.
|
143
|
-
Sidekiq.redis { |conn| conn.lpush(
|
167
|
+
Sidekiq.redis { |conn| conn.lpush(target_queue, work.job) }
|
144
168
|
end
|
145
169
|
end
|
146
170
|
|
147
|
-
def reschedule_throttled(work,
|
171
|
+
def reschedule_throttled(work, target_queue)
|
148
172
|
message = JSON.parse(work.job)
|
149
173
|
job_class = message.fetch("wrapped") { message.fetch("class") { return false } }
|
150
174
|
job_args = message["args"]
|
@@ -154,7 +178,7 @@ module Sidekiq
|
|
154
178
|
# Technically, the job could processed twice if the process dies between the two lines,
|
155
179
|
# but your job should be idempotent anyway, right?
|
156
180
|
# The job running twice was already a risk with SuperFetch anyway and this doesn't really increase that risk.
|
157
|
-
Sidekiq::Client.enqueue_to_in(
|
181
|
+
Sidekiq::Client.enqueue_to_in(target_queue, retry_in(work), Object.const_get(job_class), *job_args)
|
158
182
|
work.acknowledge
|
159
183
|
end
|
160
184
|
|
data/lib/sidekiq/throttled.rb
CHANGED
@@ -102,7 +102,7 @@ module Sidekiq
|
|
102
102
|
job_class = Object.const_get(message.fetch("wrapped") { message.fetch("class") { return false } })
|
103
103
|
|
104
104
|
Registry.get job_class do |strategy|
|
105
|
-
strategy.requeue_throttled(work
|
105
|
+
strategy.requeue_throttled(work)
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-throttled
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexey Zapparov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -90,9 +90,9 @@ licenses:
|
|
90
90
|
- MIT
|
91
91
|
metadata:
|
92
92
|
homepage_uri: https://github.com/ixti/sidekiq-throttled
|
93
|
-
source_code_uri: https://github.com/ixti/sidekiq-throttled/tree/v1.5.
|
93
|
+
source_code_uri: https://github.com/ixti/sidekiq-throttled/tree/v1.5.1
|
94
94
|
bug_tracker_uri: https://github.com/ixti/sidekiq-throttled/issues
|
95
|
-
changelog_uri: https://github.com/ixti/sidekiq-throttled/blob/v1.5.
|
95
|
+
changelog_uri: https://github.com/ixti/sidekiq-throttled/blob/v1.5.1/CHANGES.md
|
96
96
|
rubygems_mfa_required: 'true'
|
97
97
|
post_install_message:
|
98
98
|
rdoc_options: []
|