From d298f372e6007cfefa481786762a513414c897e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Barri=C3=A9?= Date: Mon, 3 Jun 2024 23:12:23 +0200 Subject: [PATCH] Make sure the run cursor is saved in the job If a job starts without a cursor (i.e. after a run is resumed), but the run has a cursor, we do use the cursor from the run in build_enumerator. However, we don't store the cursor on the job itself at this point. If the first iteration fails, we go through the `on_error` callback and store the job cursor, which is `nil`, on the run, effectively losing the progress previously made on the run. This fixes this issue by always storing the cursor on the job in `build_enumerator`, making sure the job and run have the same cursor. --- .../concerns/maintenance_tasks/task_job_concern.rb | 1 + test/jobs/maintenance_tasks/task_job_test.rb | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/app/jobs/concerns/maintenance_tasks/task_job_concern.rb b/app/jobs/concerns/maintenance_tasks/task_job_concern.rb index af9ec6258..918c1ee6e 100644 --- a/app/jobs/concerns/maintenance_tasks/task_job_concern.rb +++ b/app/jobs/concerns/maintenance_tasks/task_job_concern.rb @@ -32,6 +32,7 @@ def retry_on(*, **) def build_enumerator(_run, cursor:) cursor ||= @run.cursor + self.cursor_position = cursor @collection_enum = @task.enumerator_builder(cursor: cursor) @collection_enum ||= case (collection = @task.collection) diff --git a/test/jobs/maintenance_tasks/task_job_test.rb b/test/jobs/maintenance_tasks/task_job_test.rb index c4dcee7de..b2bc591b5 100644 --- a/test/jobs/maintenance_tasks/task_job_test.rb +++ b/test/jobs/maintenance_tasks/task_job_test.rb @@ -237,6 +237,17 @@ class << self assert_equal "0", @run.reload.cursor end + test ".perform_now persists cursor when there's an error" do + run = Run.create!(task_name: "Maintenance::ErrorTask") + + TaskJob.perform_now(run) + assert_equal "1", run.reload.cursor + + run.enqueued! + TaskJob.perform_now(run) + assert_equal "1", run.reload.cursor + end + test ".perform_now starts job from cursor position when job resumes" do @run.update!(cursor: "0")