Skip to content

Commit db794fc

Browse files
committedMar 6, 2024
Sidekiq redis-client gem compatibility
1 parent c949f44 commit db794fc

File tree

2 files changed

+71
-101
lines changed

2 files changed

+71
-101
lines changed
 

‎lib/sidekiq/batch.rb

+70-100
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,11 @@ class NoBlockGivenError < StandardError; end
1616

1717
def initialize(existing_bid = nil)
1818
@bid = existing_bid || SecureRandom.urlsafe_base64(10)
19-
@existing = !(!existing_bid || existing_bid.empty?) # Basically existing_bid.present?
19+
@existing = !(!existing_bid || existing_bid.empty?) # Basically existing_bid.present?
2020
@initialized = false
2121
@created_at = Time.now.utc.to_f
22-
@bidkey = "BID-" + @bid.to_s
23-
@queued_jids = []
24-
@pending_jids = []
25-
sidekiq_config = Sidekiq.const_defined?('MAJOR') && Sidekiq::MAJOR >= 7 ? (Thread.current[:sidekiq_capsule]&.config || Sidekiq.default_configuration) : Sidekiq.options
26-
@incremental_push = sidekiq_config[:batch_push_interval]&.present?
27-
@batch_push_interval = sidekiq_config[:batch_push_interval]
22+
@bidkey = 'BID-' + @bid.to_s
23+
@ready_to_queue = []
2824
end
2925

3026
def description=(description)
@@ -43,14 +39,13 @@ def callback_batch=(callback_batch)
4339
end
4440

4541
def on(event, callback, options = {})
46-
return unless %w(success complete).include?(event.to_s)
42+
return unless %w[success complete].include?(event.to_s)
43+
4744
callback_key = "#{@bidkey}-callbacks-#{event}"
4845
Sidekiq.redis do |r|
4946
r.multi do |pipeline|
50-
pipeline.sadd(callback_key, [JSON.unparse({
51-
callback: callback,
52-
opts: options
53-
})])
47+
json_params = JSON.unparse({ callback:, opts: options })
48+
pipeline.sadd(callback_key, json_params)
5449
pipeline.expire(callback_key, BID_EXPIRE_TTL)
5550
end
5651
end
@@ -59,95 +54,64 @@ def on(event, callback, options = {})
5954
def jobs
6055
raise NoBlockGivenError unless block_given?
6156

62-
bid_data, Thread.current[:bid_data] = Thread.current[:bid_data], []
57+
bid_data = Thread.current[:bid_data]
58+
Thread.current[:bid_data] = []
6359

6460
begin
6561
if !@existing && !@initialized
6662
parent_bid = Thread.current[:batch].bid if Thread.current[:batch]
6763

6864
Sidekiq.redis do |r|
6965
r.multi do |pipeline|
70-
pipeline.hset(@bidkey, "created_at", @created_at)
66+
pipeline.hset(@bidkey, 'created_at', @created_at)
67+
pipeline.hset(@bidkey, 'parent_bid', parent_bid.to_s) if parent_bid
7168
pipeline.expire(@bidkey, BID_EXPIRE_TTL)
72-
if parent_bid
73-
pipeline.hset(@bidkey, "parent_bid", parent_bid.to_s)
74-
pipeline.hincrby("BID-#{parent_bid}", "children", 1)
75-
end
7669
end
7770
end
7871

7972
@initialized = true
8073
end
8174

82-
@queued_jids = []
83-
@pending_jids = []
75+
@ready_to_queue = []
8476

8577
begin
8678
parent = Thread.current[:batch]
8779
Thread.current[:batch] = self
88-
Thread.current[:parent_bid] = parent_bid
8980
yield
9081
ensure
9182
Thread.current[:batch] = parent
92-
Thread.current[:parent_bid] = nil
9383
end
9484

95-
return [] if @queued_jids.size == 0
96-
conditional_redis_increment!(true)
85+
return [] if @ready_to_queue.size == 0
9786

9887
Sidekiq.redis do |r|
9988
r.multi do |pipeline|
10089
if parent_bid
90+
pipeline.hincrby("BID-#{parent_bid}", 'children', 1)
91+
pipeline.hincrby("BID-#{parent_bid}", 'total', @ready_to_queue.size)
10192
pipeline.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
10293
end
10394

95+
pipeline.hincrby(@bidkey, 'pending', @ready_to_queue.size)
96+
pipeline.hincrby(@bidkey, 'total', @ready_to_queue.size)
10497
pipeline.expire(@bidkey, BID_EXPIRE_TTL)
10598

106-
pipeline.sadd(@bidkey + "-jids", [@queued_jids.flatten])
107-
pipeline.expire(@bidkey + "-jids", BID_EXPIRE_TTL)
99+
# binding.break
100+
@ready_to_queue.each do |ready_to_queue|
101+
pipeline.sadd(@bidkey + '-jids', ready_to_queue)
102+
end
103+
pipeline.expire(@bidkey + '-jids', BID_EXPIRE_TTL)
108104
end
109105
end
110106

111-
@queued_jids
107+
@ready_to_queue
112108
ensure
113109
Thread.current[:bid_data] = bid_data
114110
end
115111
end
116112

117113
def increment_job_queue(jid)
118-
@queued_jids << jid
119-
@pending_jids << jid
120-
conditional_redis_increment!
121-
end
122-
123-
def conditional_redis_increment!(force=false)
124-
if should_increment? || force
125-
parent_bid = Thread.current[:parent_bid]
126-
Sidekiq.redis do |r|
127-
r.multi do |pipeline|
128-
if parent_bid
129-
pipeline.hincrby("BID-#{parent_bid}", "total", @pending_jids.length)
130-
pipeline.expire("BID-#{parent_bid}", BID_EXPIRE_TTL)
131-
end
132-
133-
pipeline.hincrby(@bidkey, "pending", @pending_jids.length)
134-
pipeline.hincrby(@bidkey, "total", @pending_jids.length)
135-
pipeline.expire(@bidkey, BID_EXPIRE_TTL)
136-
end
137-
end
138-
@pending_jids = []
139-
end
140-
end
141-
142-
def should_increment?
143-
return false unless @incremental_push
144-
return true if @batch_push_interval == 0 || @queued_jids.length == 1
145-
now = Time.now.to_f
146-
@last_increment ||= now
147-
if @last_increment + @batch_push_interval > now
148-
@last_increment = now
149-
return true
150-
end
114+
@ready_to_queue << jid
151115
end
152116

153117
def invalidate_all
@@ -158,14 +122,14 @@ def invalidate_all
158122

159123
def parent_bid
160124
Sidekiq.redis do |r|
161-
r.hget(@bidkey, "parent_bid")
125+
r.hget(@bidkey, 'parent_bid')
162126
end
163127
end
164128

165129
def parent
166-
if parent_bid
167-
Sidekiq::Batch.new(parent_bid)
168-
end
130+
return unless parent_bid
131+
132+
Sidekiq::Batch.new(parent_bid)
169133
end
170134

171135
def valid?(batch = self)
@@ -178,6 +142,7 @@ def valid?(batch = self)
178142
def persist_bid_attr(attribute, value)
179143
Sidekiq.redis do |r|
180144
r.multi do |pipeline|
145+
value = value.to_s if value.in? [true, false]
181146
pipeline.hset(@bidkey, attribute, value)
182147
pipeline.expire(@bidkey, BID_EXPIRE_TTL)
183148
end
@@ -188,13 +153,14 @@ class << self
188153
def process_failed_job(bid, jid)
189154
_, pending, failed, children, complete, parent_bid = Sidekiq.redis do |r|
190155
r.multi do |pipeline|
191-
pipeline.sadd("BID-#{bid}-failed", [jid])
156+
jids = [jid]
157+
jids.each { |jid| pipeline.sadd("BID-#{bid}-failed", jid) }
192158

193-
pipeline.hincrby("BID-#{bid}", "pending", 0)
159+
pipeline.hincrby("BID-#{bid}", 'pending', 0)
194160
pipeline.scard("BID-#{bid}-failed")
195-
pipeline.hincrby("BID-#{bid}", "children", 0)
161+
pipeline.hincrby("BID-#{bid}", 'children', 0)
196162
pipeline.scard("BID-#{bid}-complete")
197-
pipeline.hget("BID-#{bid}", "parent_bid")
163+
pipeline.hget("BID-#{bid}", 'parent_bid')
198164

199165
pipeline.expire("BID-#{bid}-failed", BID_EXPIRE_TTL)
200166
end
@@ -204,41 +170,44 @@ def process_failed_job(bid, jid)
204170
if parent_bid
205171
Sidekiq.redis do |r|
206172
r.multi do |pipeline|
207-
pipeline.hincrby("BID-#{parent_bid}", "pending", 1)
208-
pipeline.sadd("BID-#{parent_bid}-failed", [jid])
173+
pipeline.hincrby("BID-#{parent_bid}", 'pending', 1)
174+
jids = [jid]
175+
jids.each { |jid| pipeline.sadd("BID-#{parent_bid}-failed", jid) }
209176
pipeline.expire("BID-#{parent_bid}-failed", BID_EXPIRE_TTL)
210177
end
211178
end
212179
end
213180

214-
if pending.to_i == failed.to_i && children == complete
215-
enqueue_callbacks(:complete, bid)
216-
end
181+
return unless pending.to_i == failed.to_i && children == complete
182+
183+
enqueue_callbacks(:complete, bid)
217184
end
218185

219186
def process_successful_job(bid, jid)
220187
failed, pending, children, complete, success, total, parent_bid = Sidekiq.redis do |r|
221188
r.multi do |pipeline|
222189
pipeline.scard("BID-#{bid}-failed")
223-
pipeline.hincrby("BID-#{bid}", "pending", -1)
224-
pipeline.hincrby("BID-#{bid}", "children", 0)
190+
pipeline.hincrby("BID-#{bid}", 'pending', -1)
191+
pipeline.hincrby("BID-#{bid}", 'children', 0)
225192
pipeline.scard("BID-#{bid}-complete")
226193
pipeline.scard("BID-#{bid}-success")
227-
pipeline.hget("BID-#{bid}", "total")
228-
pipeline.hget("BID-#{bid}", "parent_bid")
194+
pipeline.hget("BID-#{bid}", 'total')
195+
pipeline.hget("BID-#{bid}", 'parent_bid')
196+
197+
jids = [jid]
198+
jids.each { |jid| pipeline.srem("BID-#{bid}-failed", jid) }
199+
jids.each { |jid| pipeline.srem("BID-#{bid}-jids", jid) }
229200

230-
pipeline.srem("BID-#{bid}-failed", [jid])
231-
pipeline.srem("BID-#{bid}-jids", [jid])
232201
pipeline.expire("BID-#{bid}", BID_EXPIRE_TTL)
233202
end
234203
end
235204

236205
all_success = pending.to_i.zero? && children == success
237206
# if complete or successfull call complete callback (the complete callback may then call successful)
238-
if (pending.to_i == failed.to_i && children == complete) || all_success
239-
enqueue_callbacks(:complete, bid)
240-
enqueue_callbacks(:success, bid) if all_success
241-
end
207+
return unless (pending.to_i == failed.to_i && children == complete) || all_success
208+
209+
enqueue_callbacks(:complete, bid)
210+
enqueue_callbacks(:success, bid) if all_success
242211
end
243212

244213
def enqueue_callbacks(event, bid)
@@ -250,30 +219,30 @@ def enqueue_callbacks(event, bid)
250219
pipeline.hget(batch_key, event_name)
251220
pipeline.hset(batch_key, event_name, 'true')
252221
pipeline.smembers(callback_key)
253-
pipeline.hget(batch_key, "callback_queue")
254-
pipeline.hget(batch_key, "parent_bid")
255-
pipeline.hget(batch_key, "callback_batch")
222+
pipeline.hget(batch_key, 'callback_queue')
223+
pipeline.hget(batch_key, 'parent_bid')
224+
pipeline.hget(batch_key, 'callback_batch')
256225
end
257226
end
258227

259228
return if already_processed == 'true'
260229

261-
queue ||= "default"
262-
parent_bid = !parent_bid || parent_bid.empty? ? nil : parent_bid # Basically parent_bid.blank?
230+
queue ||= 'default'
231+
parent_bid = nil if !parent_bid || parent_bid.empty? # Basically parent_bid.blank?
263232
callback_args = callbacks.reduce([]) do |memo, jcb|
264233
cb = Sidekiq.load_json(jcb)
265234
memo << [cb['callback'], event_name, cb['opts'], bid, parent_bid]
266235
end
267236

268-
opts = {"bid" => bid, "event" => event_name}
237+
opts = { 'bid' => bid, 'event' => event_name }
269238

270239
# Run callback batch finalize synchronously
271240
if callback_batch
272241
# Extract opts from cb_args or use current
273242
# Pass in stored event as callback finalize is processed on complete event
274243
cb_opts = callback_args.first&.at(2) || opts
275244

276-
Sidekiq.logger.debug {"Run callback batch bid: #{bid} event: #{event_name} args: #{callback_args.inspect}"}
245+
Sidekiq.logger.debug { "Run callback batch bid: #{bid} event: #{event_name} args: #{callback_args.inspect}" }
277246
# Finalize now
278247
finalizer = Sidekiq::Batch::Callback::Finalize.new
279248
status = Status.new bid
@@ -282,7 +251,7 @@ def enqueue_callbacks(event, bid)
282251
return
283252
end
284253

285-
Sidekiq.logger.debug {"Enqueue callback bid: #{bid} event: #{event_name} args: #{callback_args.inspect}"}
254+
Sidekiq.logger.debug { "Enqueue callback bid: #{bid} event: #{event_name} args: #{callback_args.inspect}" }
286255

287256
if callback_args.empty?
288257
# Finalize now
@@ -291,40 +260,41 @@ def enqueue_callbacks(event, bid)
291260
finalizer.dispatch(status, opts)
292261
else
293262
# Otherwise finalize in sub batch complete callback
294-
cb_batch = self.new
263+
cb_batch = new
295264
cb_batch.callback_batch = 'true'
296-
Sidekiq.logger.debug {"Adding callback batch: #{cb_batch.bid} for batch: #{bid}"}
297-
cb_batch.on(:complete, "Sidekiq::Batch::Callback::Finalize#dispatch", opts)
265+
Sidekiq.logger.debug { "Adding callback batch: #{cb_batch.bid} for batch: #{bid}" }
266+
cb_batch.on(:complete, 'Sidekiq::Batch::Callback::Finalize#dispatch', opts)
298267
cb_batch.jobs do
299268
push_callbacks callback_args, queue
300269
end
301270
end
302271
end
303272

304273
def cleanup_redis(bid)
305-
Sidekiq.logger.debug {"Cleaning redis of batch #{bid}"}
274+
Sidekiq.logger.debug { "Cleaning redis of batch #{bid}" }
306275
Sidekiq.redis do |r|
307276
r.del(
308277
"BID-#{bid}",
309278
"BID-#{bid}-callbacks-complete",
310279
"BID-#{bid}-callbacks-success",
311280
"BID-#{bid}-failed",
312-
313281
"BID-#{bid}-success",
314282
"BID-#{bid}-complete",
315-
"BID-#{bid}-jids",
283+
"BID-#{bid}-jids"
316284
)
317285
end
318286
end
319287

320-
private
288+
private
289+
290+
def push_callbacks(args, queue)
291+
return if args.empty?
321292

322-
def push_callbacks args, queue
323293
Sidekiq::Client.push_bulk(
324294
'class' => Sidekiq::Batch::Callback::Worker,
325295
'args' => args,
326296
'queue' => queue
327-
) unless args.empty?
297+
)
328298
end
329299
end
330300
end

‎lib/sidekiq/batch/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Sidekiq
22
class Batch
3-
VERSION = '0.1.9'.freeze
3+
VERSION = '0.2.0'.freeze
44
end
55
end

0 commit comments

Comments
 (0)
Please sign in to comment.