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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d5819912372e26634558752740bc154c4d22899b42925740b86152433744740
4
- data.tar.gz: dadcea04012b95e0349728c573a3253d86bae7920ee5844b1df9fb80933c2267
3
+ metadata.gz: 7a601fd050b147fd24ab88416d29273f0cca950c7e540c6303e1c0bb9c47f66d
4
+ data.tar.gz: 72ebc4a88c60c09faa9922c4f305fbe4374a90ebcafa62f149b83cbae6a356a6
5
5
  SHA512:
6
- metadata.gz: cf81c1a319d6f4af5c5a06f5df95dd99ad44a405f152cfda5b4c6123d4692b93d23137ab12422d6b83c82090dc422b15b441f34ed43dc1868933d54354c1326d
7
- data.tar.gz: f72803ff9a84bb3cc729869dc1105dcc9f9581c7c4c59eb2bb8a28594a7fe0df49e9b064dbae2c1f46020790637769196f98b5b38a0f77f2cb858f1b6d928679
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
- def initialize(name, concurrency: nil, threshold: nil, key_suffix: nil, observer: nil)
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
- raise ArgumentError, "Neither :concurrency nor :threshold given" unless @concurrency.any? || @threshold.any?
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
- # Return throttled job to be executed later. Implementation depends on the value of `with`:
76
- # :enqueue means put the job back at the end of the queue immediately
77
- # :schedule means schedule enqueueing the job for a later time when we expect to have capacity
78
- #
79
- # @param [#to_s, #call] with How to handle the throttled job
80
- # @param [#to_s, #call] to Name of the queue to re-queue the job to.
81
- # If not specified, will use the job's original queue.
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, with:, to: nil) # rubocop:disable Metrics/MethodLength
84
- # Resolve :with and :to arguments, calling them if they are Procs
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
- requeue_with = with.respond_to?(:call) ? with.call(*job_args) : with
87
- target_queue = calc_target_queue(work, to)
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 requeue_with
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, requeue_to: target_queue)
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 calc_target_queue(work, to) # rubocop:disable Metrics/MethodLength
116
- target = case to
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
- to.call(*JSON.parse(work.job)["args"])
142
+ requeue_to.call(*JSON.parse(work.job)["args"])
119
143
  when NilClass
120
144
  work.queue
121
145
  when String, Symbol
122
- to.to_s
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, requeue_to)
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 = requeue_to if requeue_to
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(requeue_to, work.job) }
167
+ Sidekiq.redis { |conn| conn.lpush(target_queue, work.job) }
144
168
  end
145
169
  end
146
170
 
147
- def reschedule_throttled(work, requeue_to:)
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(requeue_to, retry_in(work), Object.const_get(job_class), *job_args)
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
 
@@ -3,6 +3,6 @@
3
3
  module Sidekiq
4
4
  module Throttled
5
5
  # Gem version
6
- VERSION = "1.5.0"
6
+ VERSION = "1.5.1"
7
7
  end
8
8
  end
@@ -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, **job_class.sidekiq_throttled_requeue_options)
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.0
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-17 00:00:00.000000000 Z
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.0
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.0/CHANGES.md
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: []