job-iteration 1.3.5 → 1.3.6
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/.github/workflows/ci.yml +10 -6
- data/CHANGELOG.md +7 -3
- data/Gemfile.lock +24 -22
- data/gemfiles/rails_6_1.gemfile +12 -0
- data/gemfiles/rails_7_0.gemfile +6 -0
- data/lib/job-iteration/active_record_batch_enumerator.rb +2 -0
- data/lib/job-iteration/active_record_cursor.rb +1 -0
- data/lib/job-iteration/active_record_enumerator.rb +1 -0
- data/lib/job-iteration/enumerator_builder.rb +2 -0
- data/lib/job-iteration/iteration.rb +20 -12
- data/lib/job-iteration/throttle_enumerator.rb +1 -2
- data/lib/job-iteration/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2f1dea81ba8267470285bbd858ace091200060cc0695dfa8a986293139806a4d
|
|
4
|
+
data.tar.gz: 23affca4d929d7bfafbf9989eb152a65fe3831d380b79b877a31469854768871
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 163fd0b5034c8e0f06fc6f3e8c39f31a8b02286a7d51cc7602ead690cf8696299883c334bf5c57414dc7ba07f48faec157fdc7c602e61cbc2a42b398e23e39aa
|
|
7
|
+
data.tar.gz: 74634403a068cbccdce59b9ca526cbb97a83dbef2f34dad535385e3d4984d1967dd43748ee32ac0c80fa520ce2a137c33be15e32c2ed0a05e3c7957f85173445
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name: CI
|
|
2
2
|
|
|
3
|
-
on: [push]
|
|
3
|
+
on: [push, pull_request]
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
6
|
build:
|
|
@@ -13,23 +13,27 @@ jobs:
|
|
|
13
13
|
- 6379:6379
|
|
14
14
|
strategy:
|
|
15
15
|
matrix:
|
|
16
|
-
ruby: ["2.6", "2.7", "3.0"]
|
|
17
|
-
gemfile: [rails_5_2, rails_6_0, rails_edge]
|
|
16
|
+
ruby: ["2.6", "2.7", "3.0", "3.1"]
|
|
17
|
+
gemfile: [rails_5_2, rails_6_0, rails_6_1, rails_7_0, rails_edge]
|
|
18
18
|
exclude:
|
|
19
|
+
- ruby: "2.6"
|
|
20
|
+
gemfile: rails_7_0
|
|
19
21
|
- ruby: "2.6"
|
|
20
22
|
gemfile: rails_edge
|
|
21
23
|
- ruby: "3.0"
|
|
22
24
|
gemfile: rails_5_2
|
|
23
|
-
include:
|
|
24
25
|
- ruby: "3.1"
|
|
25
|
-
gemfile:
|
|
26
|
+
gemfile: rails_5_2
|
|
27
|
+
- ruby: "3.1"
|
|
28
|
+
gemfile: rails_6_0
|
|
29
|
+
include:
|
|
26
30
|
- ruby: head
|
|
27
31
|
gemfile: rails_edge
|
|
28
32
|
env:
|
|
29
33
|
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
|
|
30
34
|
steps:
|
|
31
35
|
- name: Check out code
|
|
32
|
-
uses: actions/checkout@
|
|
36
|
+
uses: actions/checkout@v3
|
|
33
37
|
- name: Set up Ruby ${{ matrix.ruby }}
|
|
34
38
|
uses: ruby/setup-ruby@v1
|
|
35
39
|
with:
|
data/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
### Master (unreleased)
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## v1.3.6 (Mar 9, 2022)
|
|
4
|
+
|
|
5
|
+
- [190](https://github.com/Shopify/job-iteration/pull/190) - Fix updating `times_interrupted` and `total_time` when job is throttled
|
|
6
|
+
|
|
7
|
+
## v1.3.5 (Feb 10, 2022)
|
|
4
8
|
|
|
5
9
|
- [183](https://github.com/Shopify/job-iteration/pull/183) - Add `JobIteration::EnumeratorBuilder#build_csv_enumerator`
|
|
6
10
|
|
|
7
|
-
##
|
|
11
|
+
## v1.3.4 (Jan 18, 2022)
|
|
8
12
|
|
|
9
13
|
- [174](https://github.com/Shopify/job-iteration/pull/174) - Fix Ruby 3.2 compatibility
|
|
10
14
|
|
|
11
|
-
##
|
|
15
|
+
## v1.3.3 (Nov 17, 2021)
|
|
12
16
|
- [153](https://github.com/Shopify/job-iteration/pull/153) - Re-enqueue jobs only after shutdown hooks have run
|
|
13
17
|
|
|
14
18
|
## v1.3.2 (Nov 12, 2021)
|
data/Gemfile.lock
CHANGED
|
@@ -7,21 +7,21 @@ GIT
|
|
|
7
7
|
PATH
|
|
8
8
|
remote: .
|
|
9
9
|
specs:
|
|
10
|
-
job-iteration (1.3.
|
|
10
|
+
job-iteration (1.3.6)
|
|
11
11
|
activejob (>= 5.2)
|
|
12
12
|
|
|
13
13
|
GEM
|
|
14
14
|
remote: https://rubygems.org/
|
|
15
15
|
specs:
|
|
16
|
-
activejob (6.1.4.
|
|
17
|
-
activesupport (= 6.1.4.
|
|
16
|
+
activejob (6.1.4.6)
|
|
17
|
+
activesupport (= 6.1.4.6)
|
|
18
18
|
globalid (>= 0.3.6)
|
|
19
|
-
activemodel (6.1.4.
|
|
20
|
-
activesupport (= 6.1.4.
|
|
21
|
-
activerecord (6.1.4.
|
|
22
|
-
activemodel (= 6.1.4.
|
|
23
|
-
activesupport (= 6.1.4.
|
|
24
|
-
activesupport (6.1.4.
|
|
19
|
+
activemodel (6.1.4.6)
|
|
20
|
+
activesupport (= 6.1.4.6)
|
|
21
|
+
activerecord (6.1.4.6)
|
|
22
|
+
activemodel (= 6.1.4.6)
|
|
23
|
+
activesupport (= 6.1.4.6)
|
|
24
|
+
activesupport (6.1.4.6)
|
|
25
25
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
26
26
|
i18n (>= 1.6, < 2)
|
|
27
27
|
minitest (>= 5.1)
|
|
@@ -39,7 +39,7 @@ GEM
|
|
|
39
39
|
database_cleaner-core (2.0.1)
|
|
40
40
|
globalid (1.0.0)
|
|
41
41
|
activesupport (>= 5.0)
|
|
42
|
-
i18n (1.
|
|
42
|
+
i18n (1.10.0)
|
|
43
43
|
concurrent-ruby (~> 1.0)
|
|
44
44
|
method_source (1.0.0)
|
|
45
45
|
minitest (5.15.0)
|
|
@@ -49,7 +49,7 @@ GEM
|
|
|
49
49
|
mustermann (1.1.1)
|
|
50
50
|
ruby2_keywords (~> 0.0.1)
|
|
51
51
|
parallel (1.21.0)
|
|
52
|
-
parser (3.1.
|
|
52
|
+
parser (3.1.1.0)
|
|
53
53
|
ast (~> 2.4.1)
|
|
54
54
|
pry (0.14.1)
|
|
55
55
|
coderay (~> 1.1)
|
|
@@ -62,7 +62,7 @@ GEM
|
|
|
62
62
|
redis (4.6.0)
|
|
63
63
|
redis-namespace (1.8.1)
|
|
64
64
|
redis (>= 3.0.4)
|
|
65
|
-
regexp_parser (2.2.
|
|
65
|
+
regexp_parser (2.2.1)
|
|
66
66
|
resque (2.2.0)
|
|
67
67
|
mono_logger (~> 1.0)
|
|
68
68
|
multi_json (~> 1.0)
|
|
@@ -70,22 +70,22 @@ GEM
|
|
|
70
70
|
sinatra (>= 0.9.2)
|
|
71
71
|
vegas (~> 0.1.2)
|
|
72
72
|
rexml (3.2.5)
|
|
73
|
-
rubocop (1.
|
|
73
|
+
rubocop (1.25.1)
|
|
74
74
|
parallel (~> 1.10)
|
|
75
|
-
parser (>= 3.
|
|
75
|
+
parser (>= 3.1.0.0)
|
|
76
76
|
rainbow (>= 2.2.2, < 4.0)
|
|
77
77
|
regexp_parser (>= 1.8, < 3.0)
|
|
78
78
|
rexml
|
|
79
79
|
rubocop-ast (>= 1.15.1, < 2.0)
|
|
80
80
|
ruby-progressbar (~> 1.7)
|
|
81
81
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
82
|
-
rubocop-ast (1.
|
|
83
|
-
parser (>= 3.
|
|
84
|
-
rubocop-shopify (2.
|
|
85
|
-
rubocop (~> 1.
|
|
82
|
+
rubocop-ast (1.16.0)
|
|
83
|
+
parser (>= 3.1.1.0)
|
|
84
|
+
rubocop-shopify (2.5.0)
|
|
85
|
+
rubocop (~> 1.25)
|
|
86
86
|
ruby-progressbar (1.11.0)
|
|
87
87
|
ruby2_keywords (0.0.5)
|
|
88
|
-
sidekiq (6.4.
|
|
88
|
+
sidekiq (6.4.1)
|
|
89
89
|
connection_pool (>= 2.2.2)
|
|
90
90
|
rack (~> 2.0)
|
|
91
91
|
redis (>= 4.2.0)
|
|
@@ -94,15 +94,17 @@ GEM
|
|
|
94
94
|
rack (~> 2.2)
|
|
95
95
|
rack-protection (= 2.1.0)
|
|
96
96
|
tilt (~> 2.0)
|
|
97
|
-
sorbet-runtime (0.5.
|
|
97
|
+
sorbet-runtime (0.5.9724)
|
|
98
98
|
tilt (2.0.10)
|
|
99
99
|
tzinfo (2.0.4)
|
|
100
100
|
concurrent-ruby (~> 1.0)
|
|
101
101
|
unicode-display_width (2.1.0)
|
|
102
102
|
vegas (0.1.11)
|
|
103
103
|
rack (>= 1.0.0)
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
webrick (1.7.0)
|
|
105
|
+
yard (0.9.27)
|
|
106
|
+
webrick (~> 1.7.0)
|
|
107
|
+
zeitwerk (2.5.4)
|
|
106
108
|
|
|
107
109
|
PLATFORMS
|
|
108
110
|
ruby
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
eval_gemfile "../Gemfile"
|
|
4
|
+
|
|
5
|
+
if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new("3.1")
|
|
6
|
+
gem "net-imap", require: false
|
|
7
|
+
gem "net-pop", require: false
|
|
8
|
+
gem "net-smtp", require: false
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
gem "activejob", "~> 6.1.0"
|
|
12
|
+
gem "activerecord", "~> 6.1.0"
|
|
@@ -34,6 +34,7 @@ module JobIteration
|
|
|
34
34
|
|
|
35
35
|
def each
|
|
36
36
|
return to_enum { size } unless block_given?
|
|
37
|
+
|
|
37
38
|
while (relation = next_batch)
|
|
38
39
|
yield relation, cursor_value
|
|
39
40
|
end
|
|
@@ -86,6 +87,7 @@ module JobIteration
|
|
|
86
87
|
|
|
87
88
|
def cursor_value
|
|
88
89
|
return @cursor.first if @cursor.size == 1
|
|
90
|
+
|
|
89
91
|
@cursor
|
|
90
92
|
end
|
|
91
93
|
|
|
@@ -43,6 +43,7 @@ module JobIteration
|
|
|
43
43
|
# Builds Enumerator objects that iterates N times and yields number starting from zero.
|
|
44
44
|
def build_times_enumerator(number, cursor:)
|
|
45
45
|
raise ArgumentError, "First argument must be an Integer" unless number.is_a?(Integer)
|
|
46
|
+
|
|
46
47
|
wrap(self, build_array_enumerator(number.times.to_a, cursor: cursor))
|
|
47
48
|
end
|
|
48
49
|
|
|
@@ -54,6 +55,7 @@ module JobIteration
|
|
|
54
55
|
if enumerable.any? { |i| defined?(ActiveRecord) && i.is_a?(ActiveRecord::Base) }
|
|
55
56
|
raise ArgumentError, "array cannot contain ActiveRecord objects"
|
|
56
57
|
end
|
|
58
|
+
|
|
57
59
|
drop =
|
|
58
60
|
if cursor.nil?
|
|
59
61
|
0
|
|
@@ -68,6 +68,7 @@ module JobIteration
|
|
|
68
68
|
|
|
69
69
|
def initialize(*arguments)
|
|
70
70
|
super
|
|
71
|
+
@job_iteration_retry_backoff = nil
|
|
71
72
|
@needs_reenqueue = false
|
|
72
73
|
self.times_interrupted = 0
|
|
73
74
|
self.total_time = 0.0
|
|
@@ -132,10 +133,11 @@ module JobIteration
|
|
|
132
133
|
end
|
|
133
134
|
|
|
134
135
|
run_callbacks(:shutdown)
|
|
136
|
+
completed = handle_completed(completed)
|
|
135
137
|
|
|
136
138
|
if @needs_reenqueue
|
|
137
139
|
reenqueue_iteration_job
|
|
138
|
-
elsif
|
|
140
|
+
elsif completed
|
|
139
141
|
run_callbacks(:complete)
|
|
140
142
|
output_interrupt_summary
|
|
141
143
|
end
|
|
@@ -157,6 +159,7 @@ module JobIteration
|
|
|
157
159
|
end
|
|
158
160
|
|
|
159
161
|
next unless job_should_exit?
|
|
162
|
+
|
|
160
163
|
self.executions -= 1 if executions > 1
|
|
161
164
|
@needs_reenqueue = true
|
|
162
165
|
return false
|
|
@@ -184,7 +187,7 @@ module JobIteration
|
|
|
184
187
|
self.times_interrupted += 1
|
|
185
188
|
|
|
186
189
|
self.already_in_queue = true if respond_to?(:already_in_queue=)
|
|
187
|
-
retry_job
|
|
190
|
+
retry_job(wait: @job_iteration_retry_backoff)
|
|
188
191
|
end
|
|
189
192
|
|
|
190
193
|
def adjust_total_time
|
|
@@ -266,18 +269,23 @@ module JobIteration
|
|
|
266
269
|
JobIteration.interruption_adapter.call || (defined?(super) && super)
|
|
267
270
|
end
|
|
268
271
|
|
|
269
|
-
def
|
|
270
|
-
# nil means that someone aborted the job but want to call the on_complete callback
|
|
271
|
-
if completed.nil?
|
|
272
|
-
completed = :finished
|
|
273
|
-
end
|
|
274
|
-
|
|
272
|
+
def handle_completed(completed)
|
|
275
273
|
case completed
|
|
276
|
-
when
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
274
|
+
when nil # someone aborted the job but wants to call the on_complete callback
|
|
275
|
+
return true
|
|
276
|
+
when true
|
|
277
|
+
return true
|
|
278
|
+
when false, :skip_complete_callbacks
|
|
279
|
+
return false
|
|
280
|
+
when Array # used by ThrottleEnumerator
|
|
281
|
+
reason, backoff = completed
|
|
282
|
+
raise "Unknown reason: #{reason}" unless reason == :retry
|
|
283
|
+
|
|
284
|
+
@job_iteration_retry_backoff = backoff
|
|
285
|
+
@needs_reenqueue = true
|
|
286
|
+
return false
|
|
280
287
|
end
|
|
288
|
+
raise "Unexpected thrown value: #{completed.inspect}"
|
|
281
289
|
end
|
|
282
290
|
|
|
283
291
|
def valid_cursor_parameter?(parameters)
|
|
@@ -31,8 +31,7 @@ module JobIteration
|
|
|
31
31
|
@enum.each do |*val|
|
|
32
32
|
if should_throttle?
|
|
33
33
|
ActiveSupport::Notifications.instrument("throttled.iteration", job_class: @job.class.name)
|
|
34
|
-
|
|
35
|
-
throw(:abort, :skip_complete_callbacks)
|
|
34
|
+
throw(:abort, [:retry, @backoff])
|
|
36
35
|
end
|
|
37
36
|
|
|
38
37
|
yielder.yield(*val)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: job-iteration
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.3.
|
|
4
|
+
version: 1.3.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-03-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -62,6 +62,8 @@ files:
|
|
|
62
62
|
- dev.yml
|
|
63
63
|
- gemfiles/rails_5_2.gemfile
|
|
64
64
|
- gemfiles/rails_6_0.gemfile
|
|
65
|
+
- gemfiles/rails_6_1.gemfile
|
|
66
|
+
- gemfiles/rails_7_0.gemfile
|
|
65
67
|
- gemfiles/rails_edge.gemfile
|
|
66
68
|
- guides/best-practices.md
|
|
67
69
|
- guides/custom-enumerator.md
|