sidekiq-clutch 2.0.2 → 2.1.0
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/CHANGELOG.md +8 -0
- data/lib/sidekiq/clutch/job_wrapper.rb +1 -4
- data/lib/sidekiq/clutch/jobs_collection.rb +3 -5
- data/lib/sidekiq/clutch/version.rb +1 -1
- data/lib/sidekiq/clutch/worker.rb +1 -1
- data/lib/sidekiq/clutch.rb +65 -9
- data/sidekiq-clutch.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d471e4ebb14bcae3bcbb03c855ab949b1029b9a2bbb0210927bc6f38b7f8906d
|
4
|
+
data.tar.gz: 5059ca6f29a0a3de77bef0060112b7bd448a64db5c18672a859fa91b70f1b7d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fec12c8483a7f59a466db621b77cf123bd4bb09671181b397926062b4f1c2a058be992581bb1a8b931394921da372ce737b3e365aff3dd420fe2562b818efc2
|
7
|
+
data.tar.gz: a9fc7e8afac8d30c45fa15766cc26eacb524b4f324ded0d6dfda9d314270dabed274831523ed728c8ec08900f9d3f6e540505ff05593daed26badac7cef08c89
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
# 2.1.0 - Sep 10, 2021
|
2
|
+
|
3
|
+
* PERF: Don't pass step data in success callback to every batch
|
4
|
+
|
5
|
+
NOTE: This changes the structure of arguments passed to Batch callbacks, though we
|
6
|
+
also handle the old way of doing it (v2.0.2 and before) so it shouldn't affect
|
7
|
+
any in-progress batches you may have running.
|
8
|
+
|
1
9
|
# 2.0.2 - Sep 24, 2020
|
2
10
|
|
3
11
|
* PERF: Delete keys based on known values, instead of a glob
|
@@ -3,9 +3,6 @@ module Sidekiq
|
|
3
3
|
class JobWrapper
|
4
4
|
include Sidekiq::Worker
|
5
5
|
|
6
|
-
# 22 days - how long a Sidekiq job can live with exponential backoff
|
7
|
-
RESULT_KEY_EXPIRATION_DURATION = 22 * 24 * 60 * 60
|
8
|
-
|
9
6
|
def perform(bid, job_class, args, last_result_key, current_result_key)
|
10
7
|
job = Object.const_get(job_class).new
|
11
8
|
assign_previous_results(job, last_result_key)
|
@@ -14,7 +11,7 @@ module Sidekiq
|
|
14
11
|
Sidekiq.redis do |redis|
|
15
12
|
redis.multi do |multi|
|
16
13
|
multi.rpush(current_result_key, result.to_json)
|
17
|
-
multi.expire(current_result_key,
|
14
|
+
multi.expire(current_result_key, TEMPORARY_KEY_EXPIRATION_DURATION)
|
18
15
|
end
|
19
16
|
end
|
20
17
|
end
|
@@ -4,7 +4,6 @@ module Sidekiq
|
|
4
4
|
def initialize(service)
|
5
5
|
@service = service
|
6
6
|
@jobs = []
|
7
|
-
@result_key_prefix = SecureRandom.uuid
|
8
7
|
@result_key_index = 0
|
9
8
|
end
|
10
9
|
|
@@ -25,19 +24,18 @@ module Sidekiq
|
|
25
24
|
@jobs << new_parallel_step unless continue_existing_parallel_step?
|
26
25
|
@jobs.last['parallel'] << [klass.name, params]
|
27
26
|
else
|
28
|
-
@jobs << { 'series' => [klass.name, params], '
|
27
|
+
@jobs << { 'series' => [klass.name, params], 'result_key_index' => next_result_key_index }
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
|
-
def
|
31
|
+
def next_result_key_index
|
33
32
|
@result_key_index += 1
|
34
|
-
"#{@result_key_prefix}-#{@result_key_index}"
|
35
33
|
end
|
36
34
|
|
37
35
|
private
|
38
36
|
|
39
37
|
def new_parallel_step
|
40
|
-
{ 'parallel' => [], '
|
38
|
+
{ 'parallel' => [], 'result_key_index' => next_result_key_index, 'parallel_key' => @service.parallel_key }
|
41
39
|
end
|
42
40
|
|
43
41
|
def continue_existing_parallel_step?
|
@@ -15,7 +15,7 @@ module Sidekiq
|
|
15
15
|
Sidekiq.redis do |redis|
|
16
16
|
redis.multi do |multi|
|
17
17
|
multi.rpush(current_result_key, result.to_json)
|
18
|
-
multi.expire(current_result_key,
|
18
|
+
multi.expire(current_result_key, TEMPORARY_KEY_EXPIRATION_DURATION)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
data/lib/sidekiq/clutch.rb
CHANGED
@@ -6,6 +6,9 @@ require 'sidekiq/clutch/job_wrapper'
|
|
6
6
|
|
7
7
|
module Sidekiq
|
8
8
|
class Clutch
|
9
|
+
# 22 days - how long a Sidekiq job can live with exponential backoff
|
10
|
+
TEMPORARY_KEY_EXPIRATION_DURATION = 22 * 24 * 60 * 60
|
11
|
+
|
9
12
|
def initialize(batch = nil)
|
10
13
|
@batch = batch || Sidekiq::Batch.new
|
11
14
|
end
|
@@ -51,9 +54,10 @@ module Sidekiq
|
|
51
54
|
def setup_batch
|
52
55
|
jobs_queue = jobs.raw.dup
|
53
56
|
step = jobs_queue.shift
|
57
|
+
set_jobs_data_in_redis(jobs_queue)
|
54
58
|
return if step.nil?
|
55
59
|
batch.callback_queue = queue if queue
|
56
|
-
batch.on(:success, Sidekiq::Clutch, '
|
60
|
+
batch.on(:success, Sidekiq::Clutch, 'key_base' => key_base, 'result_key_index' => result_key_index(step))
|
57
61
|
on_failure_name = on_failure&.name
|
58
62
|
batch.on(:complete, Sidekiq::Clutch, 'on_failure' => on_failure_name) if on_failure_name
|
59
63
|
batch.jobs do
|
@@ -68,14 +72,23 @@ module Sidekiq
|
|
68
72
|
end
|
69
73
|
|
70
74
|
def on_success(status, options)
|
71
|
-
if options['jobs']
|
72
|
-
|
75
|
+
return on_success_legacy(status, options) if options['jobs']
|
76
|
+
|
77
|
+
raise 'invariant: key_base is missing!' unless options['key_base']
|
78
|
+
raise 'invariant: result_key_index is missing!' unless options['result_key_index']
|
79
|
+
|
80
|
+
# NOTE: This is a brand new instance of Sidekiq::Clutch that Sidekiq instantiates,
|
81
|
+
# so we need to set @key_base again.
|
82
|
+
@key_base = options['key_base']
|
83
|
+
remaining_jobs = JSON.parse(Sidekiq.redis { |r| r.get(jobs_key) })
|
84
|
+
if remaining_jobs.empty?
|
85
|
+
clean_up_temporary_keys
|
73
86
|
return
|
74
87
|
end
|
75
88
|
parent_batch = Sidekiq::Batch.new(status.parent_bid)
|
76
89
|
service = self.class.new(parent_batch)
|
77
|
-
service.jobs.raw =
|
78
|
-
service.current_result_key = options['
|
90
|
+
service.jobs.raw = remaining_jobs
|
91
|
+
service.current_result_key = "#{key_base}-#{options['result_key_index']}"
|
79
92
|
service.engage
|
80
93
|
end
|
81
94
|
|
@@ -87,19 +100,61 @@ module Sidekiq
|
|
87
100
|
|
88
101
|
private
|
89
102
|
|
103
|
+
# accept old style of passing job data, will be removed in 3.0
|
104
|
+
def on_success_legacy(status, options)
|
105
|
+
@key_base = options['result_key'].sub(/-\d+$/, '')
|
106
|
+
if options['jobs'].empty?
|
107
|
+
clean_up_result_keys
|
108
|
+
return
|
109
|
+
end
|
110
|
+
parent_batch = Sidekiq::Batch.new(status.parent_bid)
|
111
|
+
service = self.class.new(parent_batch)
|
112
|
+
service.jobs.raw = options['jobs']
|
113
|
+
service.current_result_key = options['result_key']
|
114
|
+
service.engage
|
115
|
+
end
|
116
|
+
|
117
|
+
def key_base
|
118
|
+
@key_base ||= SecureRandom.uuid
|
119
|
+
end
|
120
|
+
|
121
|
+
def jobs_key
|
122
|
+
"#{key_base}-jobs"
|
123
|
+
end
|
124
|
+
|
125
|
+
def set_jobs_data_in_redis(data)
|
126
|
+
Sidekiq.redis do |redis|
|
127
|
+
redis.multi do |multi|
|
128
|
+
multi.set(jobs_key, data.to_json)
|
129
|
+
multi.expire(jobs_key, TEMPORARY_KEY_EXPIRATION_DURATION)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
90
134
|
def series_step(step)
|
91
135
|
(klass, params) = step['series']
|
92
|
-
enqueue_job(klass, params, step
|
136
|
+
enqueue_job(klass, params, result_key_index(step))
|
93
137
|
end
|
94
138
|
|
95
139
|
def parallel_step(step)
|
96
140
|
step['parallel'].each do |(klass, params)|
|
97
|
-
enqueue_job(klass, params, step
|
141
|
+
enqueue_job(klass, params, result_key_index(step))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def result_key_index(step)
|
146
|
+
if step['result_key_index']
|
147
|
+
step['result_key_index']
|
148
|
+
elsif step['result_key'] # legacy style, will be removed in 3.0
|
149
|
+
step['result_key'].split('-').last.to_i
|
150
|
+
else
|
151
|
+
raise "invariant: expected result_key_index passed in step; got: #{step.inspect}"
|
98
152
|
end
|
99
153
|
end
|
100
154
|
|
101
|
-
def enqueue_job(klass, params,
|
155
|
+
def enqueue_job(klass, params, result_key_index)
|
102
156
|
job_options = Object.const_get(klass).sidekiq_options
|
157
|
+
result_key = "#{key_base}-#{result_key_index}"
|
103
158
|
options = {
|
104
159
|
'class' => JobWrapper,
|
105
160
|
'queue' => queue || job_options['queue'],
|
@@ -111,8 +166,9 @@ module Sidekiq
|
|
111
166
|
Sidekiq::Client.push(options)
|
112
167
|
end
|
113
168
|
|
114
|
-
def
|
169
|
+
def clean_up_temporary_keys
|
115
170
|
Sidekiq.redis do |redis|
|
171
|
+
redis.del(jobs_key)
|
116
172
|
result_key_index = 1
|
117
173
|
loop do
|
118
174
|
result = redis.del("#{key_base}-#{result_key_index}")
|
data/sidekiq-clutch.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'sidekiq', '>= 5.0.0'
|
23
23
|
|
24
|
-
spec.add_development_dependency 'bundler', '~> 2.
|
24
|
+
spec.add_development_dependency 'bundler', '~> 2.2.4'
|
25
25
|
spec.add_development_dependency 'rake', '~> 13.0.1'
|
26
26
|
spec.add_development_dependency 'rspec', '~> 3.9.0'
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-clutch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Morgan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: 2.2.4
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: 2.2.4
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.1.6
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: An ergonomic wrapper API for Sidekiq Batches
|