job-iteration 1.1.10 → 1.1.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7868f8da1aee096abee4d4a1848c2242d0a7ac9bb1b456ad8385cfe6421a902e
4
- data.tar.gz: fd82a4cdfcbff16220363e1c53aa064b0cd5e599e17290aa968fdb01d8fe4002
3
+ metadata.gz: 18324439fe7b98c7f1bca543c078ddbfdff18af5a7e97a87b21b48890e919769
4
+ data.tar.gz: 3d912ea06a5a66ee841fbd605e8dfc414bd1760c61d9edf74445e79ae16a6466
5
5
  SHA512:
6
- metadata.gz: 42a601bb25a38571c97d108a8847317892a5289e2d3f8d818b68c99a49fc6d142dffcdd9191350261a89db65bf24aa3b0691057238f2416e2a0140bf16c47485
7
- data.tar.gz: 364868992c7fe4602f31d453891f4597d73d0b7b76482510d7ae9d3d3de7baf951465c5df7fcf9923592abb05b3584a9206f104bd610ab52dbbf3625c03be3f6
6
+ metadata.gz: 622368d1208ea23014188c028f832f51f899b6bdfbca8938c6396dcca48f913679ee7f41a035c5cbe0376346ea40a583c4615bd665251cf7dc36a30aeb37904a
7
+ data.tar.gz: 51931d565cffb4600141e1e96dc9a1a6b8a522589c8b0b38dc4cd1846e8d59a9f150d0d0bfcde4aaee587478af57418093a9e313b2f17c9f2c54ffb6cf18382a
@@ -1,11 +1,11 @@
1
- name: Ruby
1
+ name: CI
2
2
 
3
3
  on: [push]
4
4
 
5
5
  jobs:
6
6
  build:
7
7
  runs-on: ubuntu-latest
8
- name: Ruby ${{ matrix.ruby }}
8
+ name: Ruby ${{ matrix.ruby }} | Gemfile ${{ matrix.gemfile }}
9
9
  services:
10
10
  redis:
11
11
  image: redis
data/CHANGELOG.md CHANGED
@@ -4,13 +4,20 @@
4
4
 
5
5
  #### Bug fix
6
6
 
7
+
8
+ ## v1.1.11 (April 19, 2021)
9
+
10
+ #### Bug fix
11
+
12
+ - [73](https://github.com/Shopify/job-iteration/pull/73) - Enforce cursor be serializable
13
+
7
14
  ## v1.1.10 (March 30, 2021)
8
15
 
9
- - [69](https://github.com/Shopify/job-iteration/pull/69) Fix memory leak in ActiveRecordCursor
16
+ - [69](https://github.com/Shopify/job-iteration/pull/69) - Fix memory leak in ActiveRecordCursor
10
17
 
11
18
  ## v1.1.9 (January 6, 2021)
12
19
 
13
- - [61](https://github.com/Shopify/job-iteration/pull/61) Call `super` in `method_added`
20
+ - [61](https://github.com/Shopify/job-iteration/pull/61) - Call `super` in `method_added`
14
21
 
15
22
  ## v1.1.8 (June 8, 2020)
16
23
 
@@ -6,6 +6,28 @@ module JobIteration
6
6
  module Iteration
7
7
  extend ActiveSupport::Concern
8
8
 
9
+ class CursorError < ArgumentError
10
+ attr_reader :cursor
11
+
12
+ def initialize(message, cursor:)
13
+ super(message)
14
+ @cursor = cursor
15
+ end
16
+
17
+ def message
18
+ "#{super} (#{inspected_cursor})"
19
+ end
20
+
21
+ private
22
+
23
+ def inspected_cursor
24
+ cursor.inspect
25
+ rescue NoMethodError
26
+ # For those brave enough to try to use BasicObject as cursor. Nice try.
27
+ Object.instance_method(:inspect).bind(cursor).call
28
+ end
29
+ end
30
+
9
31
  included do |_base|
10
32
  attr_accessor(
11
33
  :cursor_position,
@@ -120,6 +142,8 @@ module JobIteration
120
142
  arguments = arguments.dup.freeze
121
143
  found_record = false
122
144
  enumerator.each do |object_from_enumerator, index|
145
+ assert_valid_cursor!(index)
146
+
123
147
  record_unit_of_work do
124
148
  found_record = true
125
149
  each_iteration(object_from_enumerator, *arguments)
@@ -176,6 +200,18 @@ module JobIteration
176
200
  EOS
177
201
  end
178
202
 
203
+ # The adapter must be able to serialize and deserialize the cursor back into an equivalent object.
204
+ # https://github.com/mperham/sidekiq/wiki/Best-Practices#1-make-your-job-parameters-small-and-simple
205
+ def assert_valid_cursor!(cursor)
206
+ return if serializable?(cursor)
207
+
208
+ raise CursorError.new(
209
+ "Cursor must be composed of objects capable of built-in (de)serialization: " \
210
+ "Strings, Integers, Floats, Arrays, Hashes, true, false, or nil.",
211
+ cursor: cursor,
212
+ )
213
+ end
214
+
179
215
  def assert_implements_methods!
180
216
  unless respond_to?(:each_iteration, true)
181
217
  raise(
@@ -251,5 +287,21 @@ module JobIteration
251
287
  end
252
288
  false
253
289
  end
290
+
291
+ SIMPLE_SERIALIZABLE_CLASSES = [String, Integer, Float, NilClass, TrueClass, FalseClass].freeze
292
+ private_constant :SIMPLE_SERIALIZABLE_CLASSES
293
+ def serializable?(object)
294
+ # Subclasses must be excluded, hence not using is_a? or ===.
295
+ if object.instance_of?(Array)
296
+ object.all? { |element| serializable?(element) }
297
+ elsif object.instance_of?(Hash)
298
+ object.all? { |key, value| serializable?(key) && serializable?(value) }
299
+ else
300
+ SIMPLE_SERIALIZABLE_CLASSES.any? { |klass| object.instance_of?(klass) }
301
+ end
302
+ rescue NoMethodError
303
+ # BasicObject doesn't respond to instance_of, but we can't serialize it anyway
304
+ false
305
+ end
254
306
  end
255
307
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JobIteration
4
- VERSION = "1.1.10"
4
+ VERSION = "1.1.11"
5
5
  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.1.10
4
+ version: 1.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-30 00:00:00.000000000 Z
11
+ date: 2021-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -45,7 +45,7 @@ executables: []
45
45
  extensions: []
46
46
  extra_rdoc_files: []
47
47
  files:
48
- - ".github/workflows/ruby.yml"
48
+ - ".github/workflows/ci.yml"
49
49
  - ".gitignore"
50
50
  - ".rubocop.yml"
51
51
  - ".yardopts"