Skip to content

Commit

Permalink
Create new API EnumeratorBuilder#active_record_on_batches_as_relation
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianna-chang-shopify committed May 12, 2021
1 parent 4e326e0 commit e9881d6
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,29 @@ class BatchesJob < ApplicationJob

def each_iteration(batch_of_comments, product_id)
# batch_of_comments will contain batches of 100 records
Comment.where(id: batch_of_comments.map(&:id)).update_all(deleted: true)
batch_of_comments.each do |comment|
DeleteCommentJob.perform_later(comment)
end
end
end
```

```ruby
class BatchesAsRelationJob < ApplicationJob
include JobIteration::Iteration

def build_enumerator(product_id, cursor:)
enumerator_builder.active_record_on_batches(
Product.find(product_id).comments,
cursor: cursor,
batch_size: 100,
as_relation: true,
)
end

def each_iteration(batch_of_comments, product_id)
# batch_of_comments will be a Comment::ActiveRecord_Relation
batch_of_comments.update_all(deleted: true)
end
end
```
Expand Down
13 changes: 13 additions & 0 deletions lib/job-iteration/enumerator_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ def build_active_record_enumerator_on_batches(scope, cursor:, **args)
wrap(self, enum)
end

# Builds Enumerator from Active Record Relation and enumerates on batches, yielding Active Record Relations.
# See documentation for #build_active_record_enumerator_on_batches.
def build_active_record_enumerator_on_batches_as_relation(scope, cursor:, **args)
enum = build_active_record_enumerator(
scope,
cursor: cursor,
as_relation: true,
**args
).batches
wrap(self, enum)
end

def build_throttle_enumerator(enum, throttle_on:, backoff:)
JobIteration::ThrottleEnumerator.new(
enum,
Expand All @@ -124,6 +136,7 @@ def build_throttle_enumerator(enum, throttle_on:, backoff:)
alias_method :array, :build_array_enumerator
alias_method :active_record_on_records, :build_active_record_enumerator_on_records
alias_method :active_record_on_batches, :build_active_record_enumerator_on_batches
alias_method :active_record_on_batches_as_relation, :build_active_record_enumerator_on_batches_as_relation
alias_method :throttle, :build_throttle_enumerator

private
Expand Down
25 changes: 25 additions & 0 deletions test/unit/active_job_iteration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,20 @@ def each_iteration(record)
end
end

class BatchActiveRecordRelationIterationJob < SimpleIterationJob
def build_enumerator(cursor:)
enumerator_builder.active_record_on_batches_as_relation(
Product.all,
cursor: cursor,
batch_size: 3,
)
end

def each_iteration(relation)
self.class.records_performed << relation
end
end

class AbortingActiveRecordIterationJob < ActiveRecordIterationJob
def each_iteration(*)
abort_strategy if self.class.records_performed.size == 2
Expand Down Expand Up @@ -412,6 +426,17 @@ def test_activerecord_batches_complete
assert_equal(processed_records, BatchActiveRecordIterationJob.records_performed.flatten.map(&:id))
end

def test_activerecord_batches_as_relation
push(BatchActiveRecordRelationIterationJob)

work_one_job
assert_jobs_in_queue(0)

records_performed = BatchActiveRecordIterationJob.records_performed
assert_equal([3, 3, 3, 1], records_performed.map(&:size))
assert(records_performed.all? { |record| record.is_a?(ActiveRecord::Relation) })
end

def test_activerecord_batches
iterate_exact_times(1.times)

Expand Down

0 comments on commit e9881d6

Please sign in to comment.