job-iteration 1.5.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +63 -37
- data/guides/iteration-how-it-works.md +4 -0
- data/lib/job-iteration/active_record_cursor.rb +14 -8
- data/lib/job-iteration/active_record_enumerator.rb +6 -6
- data/lib/job-iteration/enumerator_builder.rb +5 -5
- data/lib/job-iteration/interruption_adapters/good_job_adapter.rb +30 -0
- data/lib/job-iteration/interruption_adapters/solid_queue_adapter.rb +36 -0
- data/lib/job-iteration/interruption_adapters.rb +1 -1
- data/lib/job-iteration/iteration.rb +1 -1
- data/lib/job-iteration/version.rb +1 -1
- data/lib/job-iteration.rb +9 -9
- metadata +8 -7
- data/isogun.yml +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55bbe81f1fe209219d6dbb5aa469f027834d6b09dbdd6485b305fb4e3aa9bcb1
|
4
|
+
data.tar.gz: cf611985f1b8b6dc2cb1d00026fb53d6716ff353d0e59a96235f0e8538e1878b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8857b87a8a999ec88b584896ff7c384310badbf7c2e7c553b9b64fed108cb7756fdc365a0008766d9179c40279ed221c96eca0b363fd5283f6c7d3d676ab82f
|
7
|
+
data.tar.gz: 89e9e6d584fef095c6c04b96a369abbf710283dffe9856091eef3fc7492222bd7591f22a8ebaaa7ea76f5d3281cd2c8163ba57d37ead43b095fb08fb377aea3a
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.3.
|
1
|
+
3.3.3
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
### Main (unreleased)
|
2
|
+
|
2
3
|
Nil
|
3
4
|
|
5
|
+
## v1.6.0 (Sep 24, 2024)
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
- [464](https://github.com/Shopify/job-iteration/pull/464) - Add interruption adapter for [GoodJob](https://github.com/bensheldon/good_job).
|
10
|
+
- [505](https://github.com/Shopify/job-iteration/pull/505) - Add interruption adapter for [Solid Queue](https://github.com/rails/solid_queue).
|
11
|
+
|
12
|
+
## v1.5.1 (May 29,2024)
|
13
|
+
- [483](https://github.com/Shopify/job-iteration/pull/483) - Reverts [#456 Use Arel instead of String for AR Enumerator conditionals](https://github.com/Shopify/job-iteration/pull/456)
|
14
|
+
|
4
15
|
## v1.5.0 (May 29, 2024)
|
5
16
|
### Changes
|
6
17
|
|
data/Gemfile.lock
CHANGED
@@ -1,73 +1,92 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/brianmario/mysql2
|
3
|
-
revision:
|
3
|
+
revision: f6a9b68b42a51d1a370403f11eb88527dcb42dc6
|
4
4
|
specs:
|
5
5
|
mysql2 (0.5.6)
|
6
|
+
bigdecimal
|
6
7
|
|
7
8
|
PATH
|
8
9
|
remote: .
|
9
10
|
specs:
|
10
|
-
job-iteration (1.
|
11
|
+
job-iteration (1.6.0)
|
11
12
|
activejob (>= 5.2)
|
12
13
|
|
13
14
|
GEM
|
14
15
|
remote: https://rubygems.org/
|
15
16
|
specs:
|
16
|
-
activejob (7.
|
17
|
-
activesupport (= 7.
|
17
|
+
activejob (7.1.3.4)
|
18
|
+
activesupport (= 7.1.3.4)
|
18
19
|
globalid (>= 0.3.6)
|
19
|
-
activemodel (7.
|
20
|
-
activesupport (= 7.
|
21
|
-
activerecord (7.
|
22
|
-
activemodel (= 7.
|
23
|
-
activesupport (= 7.
|
24
|
-
|
20
|
+
activemodel (7.1.3.4)
|
21
|
+
activesupport (= 7.1.3.4)
|
22
|
+
activerecord (7.1.3.4)
|
23
|
+
activemodel (= 7.1.3.4)
|
24
|
+
activesupport (= 7.1.3.4)
|
25
|
+
timeout (>= 0.4.0)
|
26
|
+
activesupport (7.1.3.4)
|
27
|
+
base64
|
28
|
+
bigdecimal
|
25
29
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
30
|
+
connection_pool (>= 2.2.5)
|
31
|
+
drb
|
26
32
|
i18n (>= 1.6, < 2)
|
27
33
|
minitest (>= 5.1)
|
34
|
+
mutex_m
|
28
35
|
tzinfo (~> 2.0)
|
29
36
|
ast (2.4.2)
|
37
|
+
base64 (0.2.0)
|
38
|
+
bigdecimal (3.1.8)
|
30
39
|
coderay (1.1.3)
|
31
|
-
concurrent-ruby (1.
|
40
|
+
concurrent-ruby (1.3.4)
|
32
41
|
connection_pool (2.4.1)
|
33
42
|
csv (3.3.0)
|
34
|
-
|
35
|
-
|
36
|
-
|
43
|
+
drb (2.2.1)
|
44
|
+
globalid (1.2.1)
|
45
|
+
activesupport (>= 6.1)
|
46
|
+
i18n (1.14.6)
|
37
47
|
concurrent-ruby (~> 1.0)
|
38
|
-
json (2.7.
|
48
|
+
json (2.7.2)
|
39
49
|
language_server-protocol (3.17.0.3)
|
40
|
-
method_source (1.
|
41
|
-
minitest (5.
|
42
|
-
mocha (2.
|
50
|
+
method_source (1.1.0)
|
51
|
+
minitest (5.24.0)
|
52
|
+
mocha (2.4.5)
|
43
53
|
ruby2_keywords (>= 0.0.5)
|
44
54
|
mono_logger (1.1.2)
|
45
55
|
multi_json (1.15.0)
|
46
|
-
|
47
|
-
|
56
|
+
mustermann (3.0.0)
|
57
|
+
ruby2_keywords (~> 0.0.1)
|
58
|
+
mutex_m (0.2.0)
|
59
|
+
parallel (1.25.1)
|
60
|
+
parser (3.3.3.0)
|
48
61
|
ast (~> 2.4.1)
|
49
62
|
racc
|
50
63
|
pry (0.14.2)
|
51
64
|
coderay (~> 1.1)
|
52
65
|
method_source (~> 1.0)
|
53
|
-
racc (1.
|
54
|
-
rack (3.
|
66
|
+
racc (1.8.0)
|
67
|
+
rack (3.1.5)
|
68
|
+
rack-protection (4.0.0)
|
69
|
+
base64 (>= 0.1.0)
|
70
|
+
rack (>= 3.0.0, < 4)
|
71
|
+
rack-session (2.0.0)
|
72
|
+
rack (>= 3.0.0)
|
55
73
|
rainbow (3.1.1)
|
56
74
|
rake (13.2.1)
|
57
|
-
redis (5.
|
75
|
+
redis (5.3.0)
|
58
76
|
redis-client (>= 0.22.0)
|
59
|
-
redis-client (0.22.
|
77
|
+
redis-client (0.22.2)
|
60
78
|
connection_pool
|
61
79
|
redis-namespace (1.11.0)
|
62
80
|
redis (>= 4)
|
63
|
-
regexp_parser (2.9.
|
81
|
+
regexp_parser (2.9.2)
|
64
82
|
resque (2.6.0)
|
65
83
|
mono_logger (~> 1.0)
|
66
84
|
multi_json (~> 1.0)
|
67
85
|
redis-namespace (~> 1.6)
|
68
86
|
sinatra (>= 0.9.2)
|
69
|
-
rexml (3.
|
70
|
-
|
87
|
+
rexml (3.3.6)
|
88
|
+
strscan
|
89
|
+
rubocop (1.64.1)
|
71
90
|
json (~> 2.3)
|
72
91
|
language_server-protocol (>= 3.17.0)
|
73
92
|
parallel (~> 1.10)
|
@@ -78,24 +97,31 @@ GEM
|
|
78
97
|
rubocop-ast (>= 1.31.1, < 2.0)
|
79
98
|
ruby-progressbar (~> 1.7)
|
80
99
|
unicode-display_width (>= 2.4.0, < 3.0)
|
81
|
-
rubocop-ast (1.31.
|
82
|
-
parser (>= 3.3.0
|
83
|
-
rubocop-shopify (2.
|
100
|
+
rubocop-ast (1.31.3)
|
101
|
+
parser (>= 3.3.1.0)
|
102
|
+
rubocop-shopify (2.15.1)
|
84
103
|
rubocop (~> 1.51)
|
85
104
|
ruby-progressbar (1.13.0)
|
86
105
|
ruby2_keywords (0.0.5)
|
87
|
-
sidekiq (7.
|
106
|
+
sidekiq (7.2.4)
|
88
107
|
concurrent-ruby (< 2)
|
89
108
|
connection_pool (>= 2.3.0)
|
90
109
|
rack (>= 2.2.4)
|
91
|
-
redis-client (>= 0.
|
92
|
-
sinatra (
|
93
|
-
|
94
|
-
|
110
|
+
redis-client (>= 0.19.0)
|
111
|
+
sinatra (4.0.0)
|
112
|
+
mustermann (~> 3.0)
|
113
|
+
rack (>= 3.0.0, < 4)
|
114
|
+
rack-protection (= 4.0.0)
|
115
|
+
rack-session (>= 2.0.0, < 3)
|
116
|
+
tilt (~> 2.0)
|
117
|
+
sorbet-runtime (0.5.11460)
|
118
|
+
strscan (3.1.0)
|
119
|
+
tilt (2.4.0)
|
120
|
+
timeout (0.4.1)
|
95
121
|
tzinfo (2.0.6)
|
96
122
|
concurrent-ruby (~> 1.0)
|
97
123
|
unicode-display_width (2.5.0)
|
98
|
-
yard (0.9.
|
124
|
+
yard (0.9.37)
|
99
125
|
|
100
126
|
PLATFORMS
|
101
127
|
ruby
|
@@ -118,4 +144,4 @@ DEPENDENCIES
|
|
118
144
|
yard
|
119
145
|
|
120
146
|
BUNDLED WITH
|
121
|
-
2.5.
|
147
|
+
2.5.14
|
@@ -29,6 +29,10 @@ In other words, if you are trying to process 100 records but the job consistentl
|
|
29
29
|
|
30
30
|
If no retries are configured or retries are exhausted, Active Job 'bubbles up' the exception to the job backend. Retries by the backend (e.g. Sidekiq) are not supported, meaning that jobs retried by the job backend instead of Active Job will restart from the beginning.
|
31
31
|
|
32
|
+
## Stopping a job
|
33
|
+
|
34
|
+
Because jobs typically retry when exceptions are thrown, there is a special mechanism to fully stop a job that still has iterations remaining. To do this, you can `throw(:abort)`. This is then caught by job-iteration and signals that the job should complete now, regardless of its iteration state.
|
35
|
+
|
32
36
|
## Signals
|
33
37
|
|
34
38
|
It's critical to know [UNIX signals](https://www.tutorialspoint.com/unix/unix-signals-traps.htm) in order to understand how interruption works. There are two main signals that Sidekiq and Resque use: `SIGTERM` and `SIGKILL`. `SIGTERM` is the graceful termination signal which means that the process should exit _soon_, not immediately. For Iteration, it means that we have time to wait for the last iteration to finish and to push job back to the queue with the last cursor position.
|
@@ -18,8 +18,12 @@ module JobIteration
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
def initialize(relation, columns, position = nil)
|
22
|
-
@columns = columns
|
21
|
+
def initialize(relation, columns = nil, position = nil)
|
22
|
+
@columns = if columns
|
23
|
+
Array(columns)
|
24
|
+
else
|
25
|
+
Array(relation.primary_key).map { |pk| "#{relation.table_name}.#{pk}" }
|
26
|
+
end
|
23
27
|
self.position = Array.wrap(position)
|
24
28
|
raise ArgumentError, "Must specify at least one column" if columns.empty?
|
25
29
|
if relation.joins_values.present? && !@columns.all? { |column| column.to_s.include?(".") }
|
@@ -30,7 +34,7 @@ module JobIteration
|
|
30
34
|
raise ConditionNotSupportedError
|
31
35
|
end
|
32
36
|
|
33
|
-
@base_relation = relation.reorder(
|
37
|
+
@base_relation = relation.reorder(@columns.join(","))
|
34
38
|
@reached_end = false
|
35
39
|
end
|
36
40
|
|
@@ -50,10 +54,12 @@ module JobIteration
|
|
50
54
|
|
51
55
|
def update_from_record(record)
|
52
56
|
self.position = @columns.map do |column|
|
53
|
-
|
57
|
+
method = column.to_s.split(".").last
|
58
|
+
|
59
|
+
if ActiveRecord.version >= Gem::Version.new("7.1.0.alpha") && method == "id"
|
54
60
|
record.id_value
|
55
61
|
else
|
56
|
-
record.send(
|
62
|
+
record.send(method.to_sym)
|
57
63
|
end
|
58
64
|
end
|
59
65
|
end
|
@@ -83,14 +89,14 @@ module JobIteration
|
|
83
89
|
i = @position.size - 1
|
84
90
|
column = @columns[i]
|
85
91
|
conditions = if @columns.size == @position.size
|
86
|
-
column
|
92
|
+
"#{column} > ?"
|
87
93
|
else
|
88
|
-
column
|
94
|
+
"#{column} >= ?"
|
89
95
|
end
|
90
96
|
while i > 0
|
91
97
|
i -= 1
|
92
98
|
column = @columns[i]
|
93
|
-
conditions = column
|
99
|
+
conditions = "#{column} > ? OR (#{column} = ? AND (#{conditions}))"
|
94
100
|
end
|
95
101
|
ret = @position.reduce([conditions]) { |params, value| params << value << value }
|
96
102
|
ret.pop
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
3
|
+
require_relative "active_record_cursor"
|
4
4
|
module JobIteration
|
5
5
|
# Builds Enumerator based on ActiveRecord Relation. Supports enumerating on rows and batches.
|
6
6
|
# @see EnumeratorBuilder
|
@@ -11,9 +11,9 @@ module JobIteration
|
|
11
11
|
@relation = relation
|
12
12
|
@batch_size = batch_size
|
13
13
|
@columns = if columns
|
14
|
-
Array(columns)
|
14
|
+
Array(columns)
|
15
15
|
else
|
16
|
-
Array(relation.primary_key).map { |pk| relation.
|
16
|
+
Array(relation.primary_key).map { |pk| "#{relation.table_name}.#{pk}" }
|
17
17
|
end
|
18
18
|
@cursor = cursor
|
19
19
|
end
|
@@ -45,7 +45,7 @@ module JobIteration
|
|
45
45
|
|
46
46
|
def cursor_value(record)
|
47
47
|
positions = @columns.map do |column|
|
48
|
-
attribute_name = column.
|
48
|
+
attribute_name = column.to_s.split(".").last
|
49
49
|
column_value(record, attribute_name)
|
50
50
|
end
|
51
51
|
return positions.first if positions.size == 1
|
@@ -58,8 +58,8 @@ module JobIteration
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def column_value(record, attribute)
|
61
|
-
value = record.read_attribute(attribute)
|
62
|
-
case record.class.columns_hash.fetch(attribute
|
61
|
+
value = record.read_attribute(attribute.to_sym)
|
62
|
+
case record.class.columns_hash.fetch(attribute).type
|
63
63
|
when :datetime
|
64
64
|
value.strftime(SQL_DATETIME_WITH_NSEC)
|
65
65
|
else
|
@@ -1,10 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative "
|
4
|
-
require_relative "
|
5
|
-
require_relative "
|
6
|
-
require_relative "
|
7
|
-
require_relative "
|
3
|
+
require_relative "active_record_batch_enumerator"
|
4
|
+
require_relative "active_record_enumerator"
|
5
|
+
require_relative "csv_enumerator"
|
6
|
+
require_relative "throttle_enumerator"
|
7
|
+
require_relative "nested_enumerator"
|
8
8
|
require "forwardable"
|
9
9
|
|
10
10
|
module JobIteration
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "good_job"
|
5
|
+
rescue LoadError
|
6
|
+
# GoodJob is not available, no need to load the adapter
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
# GoodJob.current_thread_shutting_down? was introduced in GoodJob 3.26
|
12
|
+
gem("good_job", ">= 3.26")
|
13
|
+
rescue Gem::LoadError
|
14
|
+
warn("job-iteration's interruption adapter for GoodJob requires GoodJob 3.26 or newer")
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
module JobIteration
|
19
|
+
module InterruptionAdapters
|
20
|
+
module GoodJobAdapter
|
21
|
+
class << self
|
22
|
+
def call
|
23
|
+
!!::GoodJob.current_thread_shutting_down?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
register(:good_job, GoodJobAdapter)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require "solid_queue"
|
5
|
+
rescue LoadError
|
6
|
+
# SolidQueue is not available, no need to load the adapter
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
begin
|
11
|
+
# SolidQueue.on_worker_stop was introduced in SolidQueue 0.7.1
|
12
|
+
gem("solid_queue", ">= 0.7.1")
|
13
|
+
rescue Gem::LoadError
|
14
|
+
warn("job-iteration's interruption adapter for SolidQueue requires SolidQueue 0.7.1 or newer")
|
15
|
+
return
|
16
|
+
end
|
17
|
+
|
18
|
+
module JobIteration
|
19
|
+
module InterruptionAdapters
|
20
|
+
module SolidQueueAdapter
|
21
|
+
class << self
|
22
|
+
attr_accessor :stopping
|
23
|
+
|
24
|
+
def call
|
25
|
+
stopping
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
SolidQueue.on_worker_stop do
|
30
|
+
SolidQueueAdapter.stopping = true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
register(:solid_queue, SolidQueueAdapter)
|
35
|
+
end
|
36
|
+
end
|
@@ -4,7 +4,7 @@ require_relative "interruption_adapters/null_adapter"
|
|
4
4
|
|
5
5
|
module JobIteration
|
6
6
|
module InterruptionAdapters
|
7
|
-
BUNDLED_ADAPTERS = [:resque, :sidekiq].freeze # @api private
|
7
|
+
BUNDLED_ADAPTERS = [:good_job, :resque, :sidekiq, :solid_queue].freeze # @api private
|
8
8
|
|
9
9
|
class << self
|
10
10
|
# Returns adapter for specified name.
|
@@ -14,7 +14,7 @@ module JobIteration
|
|
14
14
|
# The time when the job starts running. If the job is interrupted and runs again, the value is updated.
|
15
15
|
attr_accessor :start_time
|
16
16
|
|
17
|
-
# The total time the job has been running, including multiple iterations.
|
17
|
+
# The total time (in seconds) the job has been running, including multiple iterations.
|
18
18
|
# The time isn't reset if the job is interrupted.
|
19
19
|
attr_accessor :total_time
|
20
20
|
|
data/lib/job-iteration.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_job"
|
4
|
-
require_relative "
|
5
|
-
require_relative "
|
6
|
-
require_relative "
|
7
|
-
require_relative "
|
8
|
-
require_relative "
|
9
|
-
require_relative "
|
4
|
+
require_relative "job-iteration/version"
|
5
|
+
require_relative "job-iteration/enumerator_builder"
|
6
|
+
require_relative "job-iteration/interruption_adapters"
|
7
|
+
require_relative "job-iteration/iteration"
|
8
|
+
require_relative "job-iteration/log_subscriber"
|
9
|
+
require_relative "job-iteration/railtie"
|
10
10
|
|
11
11
|
module JobIteration
|
12
12
|
Deprecation = ActiveSupport::Deprecation.new("2.0", "JobIteration")
|
@@ -62,9 +62,9 @@ module JobIteration
|
|
62
62
|
# Overrides interruption checks based on queue adapter.
|
63
63
|
# @deprecated - Use JobIteration::InterruptionAdapters.register(:foo, callable) instead.
|
64
64
|
def interruption_adapter=(adapter)
|
65
|
-
Deprecation.warn("Setting JobIteration.interruption_adapter is deprecated. "\
|
66
|
-
"Use JobIteration::InterruptionAdapters.register(:foo, callable) instead "\
|
67
|
-
"to register the callable (a proc, method, or other object responding to #call) "\
|
65
|
+
Deprecation.warn("Setting JobIteration.interruption_adapter is deprecated. " \
|
66
|
+
"Use JobIteration::InterruptionAdapters.register(:foo, callable) instead " \
|
67
|
+
"to register the callable (a proc, method, or other object responding to #call) " \
|
68
68
|
"as the interruption adapter for queue adapter :foo.")
|
69
69
|
@interruption_adapter = adapter
|
70
70
|
end
|
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.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -54,7 +54,6 @@ files:
|
|
54
54
|
- guides/custom-enumerator.md
|
55
55
|
- guides/iteration-how-it-works.md
|
56
56
|
- guides/throttling.md
|
57
|
-
- isogun.yml
|
58
57
|
- job-iteration.gemspec
|
59
58
|
- lib/job-iteration.rb
|
60
59
|
- lib/job-iteration/active_record_batch_enumerator.rb
|
@@ -63,9 +62,11 @@ files:
|
|
63
62
|
- lib/job-iteration/csv_enumerator.rb
|
64
63
|
- lib/job-iteration/enumerator_builder.rb
|
65
64
|
- lib/job-iteration/interruption_adapters.rb
|
65
|
+
- lib/job-iteration/interruption_adapters/good_job_adapter.rb
|
66
66
|
- lib/job-iteration/interruption_adapters/null_adapter.rb
|
67
67
|
- lib/job-iteration/interruption_adapters/resque_adapter.rb
|
68
68
|
- lib/job-iteration/interruption_adapters/sidekiq_adapter.rb
|
69
|
+
- lib/job-iteration/interruption_adapters/solid_queue_adapter.rb
|
69
70
|
- lib/job-iteration/iteration.rb
|
70
71
|
- lib/job-iteration/log_subscriber.rb
|
71
72
|
- lib/job-iteration/nested_enumerator.rb
|
@@ -79,7 +80,7 @@ licenses:
|
|
79
80
|
metadata:
|
80
81
|
changelog_uri: https://github.com/Shopify/job-iteration/blob/main/CHANGELOG.md
|
81
82
|
allowed_push_host: https://rubygems.org
|
82
|
-
post_install_message:
|
83
|
+
post_install_message:
|
83
84
|
rdoc_options: []
|
84
85
|
require_paths:
|
85
86
|
- lib
|
@@ -94,8 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
95
|
- !ruby/object:Gem::Version
|
95
96
|
version: '0'
|
96
97
|
requirements: []
|
97
|
-
rubygems_version: 3.5.
|
98
|
-
signing_key:
|
98
|
+
rubygems_version: 3.5.18
|
99
|
+
signing_key:
|
99
100
|
specification_version: 4
|
100
101
|
summary: Makes your background jobs interruptible and resumable.
|
101
102
|
test_files: []
|