Skip to content

Commit

Permalink
Return last Solid Queue job when there are several with the same Acti…
Browse files Browse the repository at this point in the history
…ve Job ID

This applies in the case of automatic retries performed by Active Job's
retrying mechanism. In that case, the failing job finishes just fine,
the exception is retried and Active Job re-enqueues the job, so for
Solid Queue, these look like different jobs with the same Active Job ID.
Normally we'd be interested in the last one only, though, so just return
that. In the future perhaps we can find a way to return all the instances
if there are more.
  • Loading branch information
rosa committed Jan 30, 2024
1 parent bfcf651 commit 57e36dc
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
2 changes: 1 addition & 1 deletion lib/active_job/queue_adapters/solid_queue_ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def discard_job(job, jobs_relation)
end

def find_job(job_id, *)
if job = SolidQueue::Job.find_by(active_job_id: job_id)
if job = SolidQueue::Job.where(active_job_id: job_id).order(:id).last
deserialize_and_proxy_solid_queue_job job
end
end
Expand Down
45 changes: 36 additions & 9 deletions test/controllers/jobs_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,51 @@
class MissionControl::Jobs::JobsControllerTest < ActionDispatch::IntegrationTest
setup do
DummyJob.queue_as :queue_1
@job = DummyJob.perform_later(42)
end

test "get job details" do
get mission_control_jobs.application_job_url(@application, @job.job_id)
job = DummyJob.perform_later(42)

get mission_control_jobs.application_job_url(@application, job.job_id)
assert_response :ok

assert_includes response.body, @job.job_id
assert_includes response.body, "queue_1"
assert_select "h1", /DummyJob\s+pending/
assert_includes response.body, job.job_id
assert_select "div.tag a", "queue_1"

get mission_control_jobs.application_job_url(@application, @job.job_id, filter: { queue_name: "queue_1" })
get mission_control_jobs.application_job_url(@application, job.job_id, filter: { queue_name: "queue_1" })
assert_response :ok

assert_includes response.body, @job.job_id
assert_includes response.body, "queue_1"
assert_select "h1", /DummyJob\s+pending/
assert_includes response.body, job.job_id
assert_select "div.tag a", "queue_1"
end

test "get jobs and job details when there are multiple instances of the same job due to automatic retries" do
job = AutoRetryingJob.perform_later
perform_enqueued_jobs_async

# Wait until the job has been executed and retried
sleep(1)

get mission_control_jobs.application_jobs_url(@application, :finished)
assert_response :ok

assert_select "tr.job", 2
assert_select "tr.job", /AutoRetryingJob\s+Enqueued less than a minute ago\s+default/

get mission_control_jobs.application_job_url(@application, job.job_id)
assert_response :ok

assert_select "h1", /AutoRetryingJob\s+failed\s+/
assert_includes response.body, job.job_id
assert_select "div.is-danger", "failed"
end

test "redirect to queue when job doesn't exist" do
get mission_control_jobs.application_job_url(@application, @job.job_id + "0", filter: { queue_name: "queue_1" })
job = DummyJob.perform_later(42)

get mission_control_jobs.application_job_url(@application, job.job_id + "0", filter: { queue_name: "queue_1" })
assert_redirected_to mission_control_jobs.application_queue_path(@application, :queue_1)
end

Expand All @@ -32,9 +58,10 @@ class MissionControl::Jobs::JobsControllerTest < ActionDispatch::IntegrationTest
travel_to 2.minutes.from_now

get mission_control_jobs.application_jobs_url(@application, :scheduled)
assert_response :ok

assert_select "tr.job", 2
assert_select "tr.job", /DummyJob\s+Enqueued 2 minutes ago\s+queue_1\s+in 1 minute/
assert_select "tr.job", /DummyJob\s+Enqueued 2 minutes ago\s+queue_1\s+less than a minute ago/
assert_select "tr.job", /DummyJob\s+Enqueued 2 minutes ago\s+queue_1\s+1 minute ago/
end
end

0 comments on commit 57e36dc

Please sign in to comment.