job-iteration 1.2.0 → 1.3.3

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: eff37be02274e3c0db10de1cf3e49a10eea5b5b838b19800d143853aee94c08f
4
- data.tar.gz: '085dc8b7eec8897393461e43fb4ece8acaddc6705165a2b6de0856cef54b1215'
3
+ metadata.gz: d715ff6962fc9ff1081d5db93be694b0f0ed3e9fc2935b0d9f252971ea8a40d0
4
+ data.tar.gz: 60571b6b588816ad637a0eaaee238adb423c230102d4a73745e0fcc3b9e41b17
5
5
  SHA512:
6
- metadata.gz: 22352326237ca16a23fc4177611187d4c6d426c07397caecd09165303726ce9ba00acaa882e35fb580b19bbe53f056ddde642298268a329dd02c88f61f82b5b7
7
- data.tar.gz: 583406e5180f2721895673aa0410a390dce378c9c30e625151b5455fa8c1331867e94cc1cf2518b8b29cb0fbe908af517ee88a88429fd5f71f34a80617f5d8e6
6
+ metadata.gz: 587952d2f628c6d43c982ee8a4fe85d409d4d39044b34aa436bf97a2dd2679d92bfcb098bb2b35380b90297359dbefddc805a188501bd464665e8199a21f673e
7
+ data.tar.gz: dc172c2fa8172ee47d2af5ed7d47513b8e1131121f6b4f8deebf534a1c7f7e38e8b01f421bf3cc1e419aec9d1c5469020e690757be1e87c35e6d6dc0db8a437c
@@ -0,0 +1,16 @@
1
+ version: 2
2
+
3
+ updates:
4
+
5
+ - package-ecosystem: bundler
6
+ directory: '/'
7
+ versioning-strategy: increase
8
+ open-pull-requests-limit: 100
9
+ insecure-external-code-execution: allow
10
+ schedule:
11
+ interval: weekly
12
+
13
+ - package-ecosystem: github-actions
14
+ directory: '/'
15
+ schedule:
16
+ interval: daily
data/.gitignore CHANGED
@@ -9,4 +9,3 @@
9
9
  .ruby-version
10
10
  .rubocop-http---shopify-github-io-ruby-style-guide-rubocop-yml
11
11
  gemfiles/*.lock
12
- Gemfile.lock
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  ### Master (unreleased)
2
2
 
3
+ ## v.1.3.3 (Nov 17, 2021)
4
+ - [153](https://github.com/Shopify/job-iteration/pull/153) - Re-enqueue jobs only after shutdown hooks have run
5
+
6
+ ## v1.3.2 (Nov 12, 2021)
7
+ - [148](https://github.com/Shopify/job-iteration/pull/148) - Revert "Do not evaluate enumerator when throttled", due to backwards incompatibility.
8
+
9
+ ## v1.3.1 (Nov 11, 2021)
10
+ - [87](https://github.com/Shopify/job-iteration/pull/87) - Do not evaluate enumerator when throttled (REVERTED)
11
+
12
+
13
+ ## v1.3.0 (Oct 7, 2021)
14
+ - [133](https://github.com/Shopify/job-iteration/pull/133) - Moves attributes out of JobIteration::Iteration included block
15
+
16
+
3
17
  ## v1.2.0 (Sept 21, 2021)
4
18
  - [107](https://github.com/Shopify/job-iteration/pull/107) - Remove broken links from README
5
19
  - [108](https://github.com/Shopify/job-iteration/pull/108) - Drop support for ruby 2.5
data/Gemfile.lock ADDED
@@ -0,0 +1,123 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ job-iteration (1.3.3)
5
+ activejob (>= 5.2)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activejob (6.1.4.1)
11
+ activesupport (= 6.1.4.1)
12
+ globalid (>= 0.3.6)
13
+ activemodel (6.1.4.1)
14
+ activesupport (= 6.1.4.1)
15
+ activerecord (6.1.4.1)
16
+ activemodel (= 6.1.4.1)
17
+ activesupport (= 6.1.4.1)
18
+ activesupport (6.1.4.1)
19
+ concurrent-ruby (~> 1.0, >= 1.0.2)
20
+ i18n (>= 1.6, < 2)
21
+ minitest (>= 5.1)
22
+ tzinfo (~> 2.0)
23
+ zeitwerk (~> 2.3)
24
+ ast (2.4.2)
25
+ coderay (1.1.3)
26
+ concurrent-ruby (1.1.9)
27
+ connection_pool (2.2.5)
28
+ database_cleaner (2.0.1)
29
+ database_cleaner-active_record (~> 2.0.0)
30
+ database_cleaner-active_record (2.0.1)
31
+ activerecord (>= 5.a)
32
+ database_cleaner-core (~> 2.0.0)
33
+ database_cleaner-core (2.0.1)
34
+ globalid (0.5.2)
35
+ activesupport (>= 5.0)
36
+ i18n (1.8.11)
37
+ concurrent-ruby (~> 1.0)
38
+ method_source (1.0.0)
39
+ minitest (5.14.4)
40
+ mocha (1.13.0)
41
+ mono_logger (1.1.1)
42
+ multi_json (1.15.0)
43
+ mustermann (1.1.1)
44
+ ruby2_keywords (~> 0.0.1)
45
+ mysql2 (0.5.3)
46
+ parallel (1.21.0)
47
+ parser (3.0.2.0)
48
+ ast (~> 2.4.1)
49
+ pry (0.14.1)
50
+ coderay (~> 1.1)
51
+ method_source (~> 1.0)
52
+ rack (2.2.3)
53
+ rack-protection (2.1.0)
54
+ rack
55
+ rainbow (3.0.0)
56
+ rake (13.0.6)
57
+ redis (4.5.1)
58
+ redis-namespace (1.8.1)
59
+ redis (>= 3.0.4)
60
+ regexp_parser (2.1.1)
61
+ resque (2.2.0)
62
+ mono_logger (~> 1.0)
63
+ multi_json (~> 1.0)
64
+ redis-namespace (~> 1.6)
65
+ sinatra (>= 0.9.2)
66
+ vegas (~> 0.1.2)
67
+ rexml (3.2.5)
68
+ rubocop (1.22.1)
69
+ parallel (~> 1.10)
70
+ parser (>= 3.0.0.0)
71
+ rainbow (>= 2.2.2, < 4.0)
72
+ regexp_parser (>= 1.8, < 3.0)
73
+ rexml
74
+ rubocop-ast (>= 1.12.0, < 2.0)
75
+ ruby-progressbar (~> 1.7)
76
+ unicode-display_width (>= 1.4.0, < 3.0)
77
+ rubocop-ast (1.12.0)
78
+ parser (>= 3.0.1.1)
79
+ rubocop-shopify (2.3.0)
80
+ rubocop (~> 1.22)
81
+ ruby-progressbar (1.11.0)
82
+ ruby2_keywords (0.0.5)
83
+ sidekiq (6.3.1)
84
+ connection_pool (>= 2.2.2)
85
+ rack (~> 2.0)
86
+ redis (>= 4.2.0)
87
+ sinatra (2.1.0)
88
+ mustermann (~> 1.0)
89
+ rack (~> 2.2)
90
+ rack-protection (= 2.1.0)
91
+ tilt (~> 2.0)
92
+ sorbet-runtime (0.5.9219)
93
+ tilt (2.0.10)
94
+ tzinfo (2.0.4)
95
+ concurrent-ruby (~> 1.0)
96
+ unicode-display_width (2.1.0)
97
+ vegas (0.1.11)
98
+ rack (>= 1.0.0)
99
+ yard (0.9.26)
100
+ zeitwerk (2.4.2)
101
+
102
+ PLATFORMS
103
+ ruby
104
+
105
+ DEPENDENCIES
106
+ activerecord
107
+ database_cleaner
108
+ globalid
109
+ i18n
110
+ job-iteration!
111
+ mocha
112
+ mysql2 (~> 0.5)
113
+ pry
114
+ rake
115
+ redis
116
+ resque
117
+ rubocop-shopify
118
+ sidekiq
119
+ sorbet-runtime
120
+ yard
121
+
122
+ BUNDLED WITH
123
+ 2.2.22
@@ -40,7 +40,7 @@ module JobIteration
40
40
  end
41
41
 
42
42
  def size
43
- (@base_relation.count + @batch_size - 1) / @batch_size # ceiling division
43
+ (@base_relation.count(:all) + @batch_size - 1) / @batch_size # ceiling division
44
44
  end
45
45
 
46
46
  private
@@ -13,7 +13,7 @@ module JobIteration
13
13
  def initialize
14
14
  super(
15
15
  "The relation cannot use ORDER BY or LIMIT due to the way how iteration with a cursor is designed. " \
16
- "You can use other ways to limit the number of rows, e.g. a WHERE condition on the primary key column."
16
+ "You can use other ways to limit the number of rows, e.g. a WHERE condition on the primary key column."
17
17
  )
18
18
  end
19
19
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "./active_record_cursor"
3
4
  module JobIteration
4
5
  # Builds Enumerator based on ActiveRecord Relation. Supports enumerating on rows and batches.
@@ -33,7 +34,7 @@ module JobIteration
33
34
  end
34
35
 
35
36
  def size
36
- @relation.count
37
+ @relation.count(:all)
37
38
  end
38
39
 
39
40
  private
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative "./active_record_batch_enumerator"
3
4
  require_relative "./active_record_enumerator"
4
5
  require_relative "./csv_enumerator"
@@ -6,6 +6,13 @@ module JobIteration
6
6
  module Iteration
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ attr_accessor(
10
+ :cursor_position,
11
+ :start_time,
12
+ :times_interrupted,
13
+ :total_time,
14
+ )
15
+
9
16
  class CursorError < ArgumentError
10
17
  attr_reader :cursor
11
18
 
@@ -29,13 +36,6 @@ module JobIteration
29
36
  end
30
37
 
31
38
  included do |_base|
32
- attr_accessor(
33
- :cursor_position,
34
- :start_time,
35
- :times_interrupted,
36
- :total_time,
37
- )
38
-
39
39
  define_callbacks :start
40
40
  define_callbacks :shutdown
41
41
  define_callbacks :complete
@@ -68,6 +68,7 @@ module JobIteration
68
68
 
69
69
  def initialize(*arguments)
70
70
  super
71
+ @needs_reenqueue = false
71
72
  self.times_interrupted = 0
72
73
  self.total_time = 0.0
73
74
  assert_implements_methods!
@@ -132,7 +133,9 @@ module JobIteration
132
133
 
133
134
  run_callbacks(:shutdown)
134
135
 
135
- if run_complete_callbacks?(completed)
136
+ if @needs_reenqueue
137
+ reenqueue_iteration_job
138
+ elsif run_complete_callbacks?(completed)
136
139
  run_callbacks(:complete)
137
140
  output_interrupt_summary
138
141
  end
@@ -141,6 +144,8 @@ module JobIteration
141
144
  def iterate_with_enumerator(enumerator, arguments)
142
145
  arguments = arguments.dup.freeze
143
146
  found_record = false
147
+ @needs_reenqueue = false
148
+
144
149
  enumerator.each do |object_from_enumerator, index|
145
150
  # Deferred until 2.0.0
146
151
  # assert_valid_cursor!(index)
@@ -153,13 +158,13 @@ module JobIteration
153
158
 
154
159
  next unless job_should_exit?
155
160
  self.executions -= 1 if executions > 1
156
- reenqueue_iteration_job
161
+ @needs_reenqueue = true
157
162
  return false
158
163
  end
159
164
 
160
165
  logger.info(
161
166
  "[JobIteration::Iteration] Enumerator found nothing to iterate! " \
162
- "times_interrupted=#{times_interrupted} cursor_position=#{cursor_position}"
167
+ "times_interrupted=#{times_interrupted} cursor_position=#{cursor_position}"
163
168
  ) unless found_record
164
169
 
165
170
  adjust_total_time
@@ -167,10 +172,8 @@ module JobIteration
167
172
  true
168
173
  end
169
174
 
170
- def record_unit_of_work
171
- ActiveSupport::Notifications.instrument("each_iteration.iteration", iteration_instrumentation_tags) do
172
- yield
173
- end
175
+ def record_unit_of_work(&block)
176
+ ActiveSupport::Notifications.instrument("each_iteration.iteration", iteration_instrumentation_tags, &block)
174
177
  end
175
178
 
176
179
  def reenqueue_iteration_job
@@ -210,7 +213,7 @@ module JobIteration
210
213
 
211
214
  raise CursorError.new(
212
215
  "Cursor must be composed of objects capable of built-in (de)serialization: " \
213
- "Strings, Integers, Floats, Arrays, Hashes, true, false, or nil.",
216
+ "Strings, Integers, Floats, Arrays, Hashes, true, false, or nil.",
214
217
  cursor: cursor,
215
218
  )
216
219
  end
@@ -227,7 +230,7 @@ module JobIteration
227
230
  parameters = method_parameters(:build_enumerator)
228
231
  unless valid_cursor_parameter?(parameters)
229
232
  raise ArgumentError, "Iteration job (#{self.class}) #build_enumerator " \
230
- "expects the keyword argument `cursor`"
233
+ "expects the keyword argument `cursor`"
231
234
  end
232
235
  else
233
236
  raise ArgumentError, "Iteration job (#{self.class}) must implement #build_enumerator " \
@@ -1,5 +1,6 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
+
3
4
  module JobIteration
4
5
  # ThrottleEnumerator allows you to throttle iterations
5
6
  # based on external signal (e.g. database health).
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JobIteration
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.3"
5
5
  end
data/lib/job-iteration.rb CHANGED
@@ -22,6 +22,7 @@ module JobIteration
22
22
 
23
23
  # Used internally for hooking into job processing frameworks like Sidekiq and Resque.
24
24
  attr_accessor :interruption_adapter
25
+
25
26
  self.interruption_adapter = -> { false }
26
27
 
27
28
  # Set if you want to use your own enumerator builder instead of default EnumeratorBuilder.
@@ -33,6 +34,7 @@ module JobIteration
33
34
  #
34
35
  # JobIteration.enumerator_builder = MyOwnBuilder
35
36
  attr_accessor :enumerator_builder
37
+
36
38
  self.enumerator_builder = JobIteration::EnumeratorBuilder
37
39
 
38
40
  def load_integrations
@@ -42,7 +44,7 @@ module JobIteration
42
44
  if loaded
43
45
  raise IntegrationLoadError,
44
46
  "#{loaded} integration has already been loaded, but #{integration} is also available. " \
45
- "Iteration will only work with one integration."
47
+ "Iteration will only work with one integration."
46
48
  end
47
49
  loaded = integration
48
50
  rescue LoadError
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.2.0
4
+ version: 1.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-22 00:00:00.000000000 Z
11
+ date: 2021-11-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -45,6 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
+ - ".github/dependabot.yml"
48
49
  - ".github/workflows/ci.yml"
49
50
  - ".gitignore"
50
51
  - ".rubocop.yml"
@@ -52,6 +53,7 @@ files:
52
53
  - CHANGELOG.md
53
54
  - CODE_OF_CONDUCT.md
54
55
  - Gemfile
56
+ - Gemfile.lock
55
57
  - LICENSE.txt
56
58
  - README.md
57
59
  - Rakefile