No supported way to cancel a job that is already executing!
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 45/100
Research direction
Look at the SolidQueue::ClaimedExecution class and its discard method that raises UndiscardableError. Understand how jobs are claimed and finalized. The goal is to design a way to signal cancellation to a running job, perhaps by adding a flag or a cooperative check, and to allow discard to work on executing jobs. Review the existing job lifecycle and the finalize method's logic.
Written by the indexing model from the issue text.
Description
Summary
SolidQueue supports cancelling a queued (ready/scheduled) job cleanly via job.discard (as clarified in #395). But there is no supported way to cancel a job that is already executing (claimed) — ClaimedExecution#discard explicitly raises:
def discard
raise UndiscardableError, "Can't discard a job in progress"
end
In Quepid we have very long "LLM as a judge" type jobs taht could run for many many minutes or hours... And you might say "oh, crap, it's not what I want" and then it's awkward. We wrote a bunch of janky code to support this.
Current behavior
Applications that want a user-facing "Cancel" button for a long-running job (ours: an AI judging run scoped to one book+judge, potentially processing hundreds of records) have no sanctioned way to request cancellation of an already-claimed job. Our workaround bypasses the guard directly:
def self.cancel book, judge
active_for(book, judge).each do |job|
if job.claimed_execution.present?
# Job is actively running — force destroy it. The job's own #perform
# loop checks for its own SolidQueue row on every iteration and stops
# as soon as it notices this row is gone.
job.claimed_execution.destroy
job.destroy
else
job.discard
end
end
end
This only works because ClaimedExecution#finalize's unless_already_finalized check (self.class.unscoped.lock.find_by(id: id)) happens to tolerate the claimed_execution row already being gone by the time the job actually finishes — but that's an internal implementation detail we're relying on, not a documented contract, and it could change between versions without notice.
It also means the running job's #perform never gets any signal that cancellation was requested other than a self-written polling loop:
cancellable = SolidQueue::Job.exists?(active_job_id: job_id)
loop do
break if cancellable && !SolidQueue::Job.exists?(active_job_id: job_id)
# ... do one unit of work ...
end
There's no cooperative "cancellation requested" flag to check cheaply, and no built-in helper for this pattern either — every app doing cooperative cancellation re-derives the same polling idiom.
Why this belongs in SolidQueue, not application code
ClaimedExecution, #finalize, and the UndiscardableError guard are all internal to SolidQueue; there's no supported extension point for "cancel this specific already-running job" without reaching past that guard into internals that could change between versions.
Related
#395 covers cancelling a scheduled (not-yet-executing) job via discard — this issue is specifically about the claimed/executing case, which that thread doesn't touch.
- Dominant language
- Ruby
- Stars
- 2.5k
- Forks
- 250
- Avg merge
- 8h 31m
- Merged PRs (30d)
- 5
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rails/solid_queue
-
Difficulty 3/5 1-2 days Newbie friendliness 65/100
rails/solid_queue#805 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
rails/solid_queue#804 · 1 comment ·
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
rails/solid_queue#802 ·
-
Difficulty 5/5 Over a week Newbie friendliness 35/100
rails/solid_queue#797 ·
-
Difficulty 4/5 3-5 days Newbie friendliness 55/100
rails/solid_queue#792 · 1 reaction ·
All issues in rails/solid_queue
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
simp/pupmod-simp-simp#395 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 80/100
simp/pupmod-simp-rsyslog#219 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
simp/pupmod-simp-pupmod#256 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100
simp/pupmod-simp-sudo#150 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 90/100