Skip to content

Commit

Permalink
Ensure cursor is converted into integer as needed
Browse files Browse the repository at this point in the history
To ensure #339's change to string cursors can occur smoothly, we ensure
we always convert the cursor into an integer when needed.

Specifically, the Array and CSV cursors MUST be integers when forwarded
to JobIteration's enumerator builders, or things break. The ActiveRecord
enumerator builder handles the conversion gracefully.

This should allow consumers to perform the cursor schema change from
bigint to string without worrying about stale code blowing up.
  • Loading branch information
sambostock committed Feb 22, 2021
1 parent 8ef283d commit b777f71
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 2 deletions.
7 changes: 5 additions & 2 deletions app/jobs/maintenance_tasks/task_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ def build_enumerator(_run, cursor:)
when ActiveRecord::Relation
enumerator_builder.active_record_on_records(collection, cursor: cursor)
when Array
enumerator_builder.build_array_enumerator(collection, cursor: cursor)
enumerator_builder.build_array_enumerator(
collection,
cursor: cursor&.to_i,
)
when CSV
JobIteration::CsvEnumerator.new(collection).rows(cursor: cursor)
JobIteration::CsvEnumerator.new(collection).rows(cursor: cursor&.to_i)
else
raise ArgumentError, "#{@task.class.name}#collection must be either "\
'an Active Record Relation, Array, or CSV.'
Expand Down
33 changes: 33 additions & 0 deletions test/jobs/maintenance_tasks/task_job_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,15 @@ class TaskJobTest < ActiveJob::TestCase
TaskJob.perform_now(@run)
end

# Remove this once string cursors are shipped (#339)
test '.perform_now handles string cursor when Array task resumes' do
@run.expects(:cursor).returns('0')

TaskJob.perform_now(@run)

assert_predicate @run, :succeeded?
end

test '.perform_now accepts Active Record Relations as collection' do
Maintenance::TestTask.any_instance.stubs(collection: Post.all)
Maintenance::TestTask.any_instance.expects(:process).times(Post.count)
Expand All @@ -207,6 +216,16 @@ class TaskJobTest < ActiveJob::TestCase
assert_predicate @run.reload, :succeeded?
end

# Remove this once string cursors are shipped (#339)
test '.perform_now handles string cursor when Active Record Relation task resumes' do
run = Run.create!(task_name: 'Maintenance::UpdatePostsTask')
run.expects(:cursor).returns(Post.pick(:id)&.to_s)

TaskJob.perform_now(run)

assert_predicate run, :succeeded?
end

test '.perform_now accepts CSVs as collection' do
Maintenance::ImportPostsTask.any_instance.expects(:process).times(5)

Expand All @@ -220,6 +239,20 @@ class TaskJobTest < ActiveJob::TestCase
assert_predicate run.reload, :succeeded?
end

# Remove this once string cursors are shipped (#339)
test '.perform_now handles string cursor when CSV task resumes' do
run = Run.new(task_name: 'Maintenance::ImportPostsTask')
run.csv_file.attach(
{ io: File.open(file_fixture('sample.csv')), filename: 'sample.csv' }
)
run.save
run.expects(:cursor).returns('0')

TaskJob.perform_now(run)

assert_predicate run, :succeeded?
end

test '.perform_now sets the Run as errored when the Task collection is invalid' do
Maintenance::TestTask.any_instance.stubs(collection: 'not a collection')

Expand Down

0 comments on commit b777f71

Please sign in to comment.