Repository navigation
Conversation
dtcristo
force-pushed
the
xenorune/coalesce-jobs
branch
from
November 7, 2026 05:40
2627df4 to
a856eb3
Compare
xenorune
force-pushed
the
xenorune/coalesce-jobs
branch
2 times, most recently
from
November 7, 2026 06:57
2138fef to
918ca08
Compare
A row ties a coalesce key to the pending job that calls with that key are discarded into. Fresh installs get it with the base schema, and existing ones through `bin/rails solid_queue:update`. Its foreign key deletes the row along with the job. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
xenorune
force-pushed
the
xenorune/coalesce-jobs
branch
3 times, most recently
from
November 7, 2026 07:51
fb3af4f to
d02d173
Compare
`coalesce key:` makes jobs with the same key share one pending job. Admission inserts the key's row unless it exists and locks it, then creates the job or discards the call into the one already there. Claiming a job releases its key, so a call made during the run queues the next job. Retries aren't coalesced. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
xenorune
force-pushed
the
xenorune/coalesce-jobs
branch
from
November 7, 2026 07:56
d02d173 to
d42f86b
Compare
dtcristo
marked this pull request as ready for review
November 7, 2026 08:11
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hey, David here.
Below is my AI-assisted implementation of basic coalescing described in #834.
What
Adds
coalesce key:to Active Job classes. Jobs enqueued with the same key share one pending job. The first creates it, and later ones, including scheduled ones, are discarded into it until a worker claims it. A job enqueued during the run then queues the next pending job.coalesce_status(:createdor:discarded) andprovider_job_idtell the caller what happened.It adds a
solid_queue_coalesce_keystable, withbin/rails solid_queue:updatefor existing installations.Why
See #834, which is the place to discuss the design. This PR is a minimal version to make that discussion concrete. It shows the approach, and leaves out edge cases a real implementation would need.
How
ActiveJob::Coalescingsits next toActiveJob::ConcurrencyControls. It addscoalesceand builds keys the wayconcurrency_keydoes, scoped to the class and batch.Job.enqueuesends coalesced jobs toSolidQueue::Job::Coalescing, the wayJob::ConcurrencyControlspairs with its Active Job counterpart. In one transaction, it inserts the key's row unless it exists, locks it, and either creates the job and records it on the row, or discards the call into the job already there. Calls with the same key wait on that lock. Database errors raiseEnqueueError, as for other jobs.Job.enqueue_allhandles coalesced jobs one at a time, in key order.ReadyExecution.claimlocks the keys of the jobs it claims in key order, the same order as bulk enqueue, and deletes them in the claim's transaction. A pending job that's deleted takes its key with it, through the foreign key.Left out on purpose: deadlock retries on MySQL, instrumentation, and keeping the key for a claimed job that's released back to the queue. An app transaction that coalesces several keys in arbitrary order can also deadlock with a claim.
🤖 Written by @dtcristo's agent (Claude Opus 5.5, GPT-6.1 Sol)