From 5dbaaf74cf9828cd6125111d735f212ab1aae2d2 Mon Sep 17 00:00:00 2001 From: Micaherb Date: Tue, 2 Jun 2026 15:44:44 -0400 Subject: [PATCH] Accept job arg in SolidQueueAdapter#stopping? for Rails 8.2 compatibility Rails 8.2 (rails/rails@6d1c401d, landed on main 2026-05-26) changed `ActiveJob::Continuable#checkpoint!` to call `queue_adapter.stopping?(self)`, passing the job instance. The upstream CHANGELOG requires every adapter that implements `stopping?` to accept an optional positional argument: > Queue adapters that implement `stopping?` must accept the job as an > optional positional argument, i.e. `def stopping?(job = nil)`, in order to > work with this version and older versions of Rails. SolidQueueAdapter relied on the `stopping?` predicate generated by `class_attribute :stopping`, which takes no arguments. Against Rails main every `checkpoint!` call raised ArgumentError, so continuable jobs never finished and `ContinuationTest#test_continuable_job_completes` failed deterministically across the entire rails_main matrix. Define `stopping?(job = nil)` explicitly. The optional arg keeps the method compatible with Rails 7.1 / 7.2 / 8.0 / 8.1 (which call with no args) and Rails 8.2+ (which passes the job). The job is currently unused -- this adapter doesn't yet support per-job interrupt reasons; that's a separate follow-up. --- lib/active_job/queue_adapters/solid_queue_adapter.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/active_job/queue_adapters/solid_queue_adapter.rb b/lib/active_job/queue_adapters/solid_queue_adapter.rb index fe5560427..51a12c21b 100644 --- a/lib/active_job/queue_adapters/solid_queue_adapter.rb +++ b/lib/active_job/queue_adapters/solid_queue_adapter.rb @@ -11,6 +11,13 @@ class SolidQueueAdapter < (Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR = class_attribute :stopping, default: false, instance_writer: false SolidQueue.on_worker_stop { self.stopping = true } + # Rails 8.2+ (rails/rails@6d1c401d) passes the job to `stopping?` from + # `ActiveJob::Continuable#checkpoint!`. Accept the optional positional + # argument so the adapter works against both old and new ActiveJob. + def stopping?(job = nil) + self.class.stopping + end + def enqueue_after_transaction_commit? true end