Skip to content

pool: treat an occupied scheduled key as a satisfied transition - #85

Merged
raphael merged 1 commit into
mainfrom
scheduler-occupied-key
Jul 26, 2026
Merged

pool: treat an occupied scheduled key as a satisfied transition#85
raphael merged 1 commit into
mainfrom
scheduler-occupied-key

Conversation

@raphael

@raphael raphael commented Jul 26, 2026

Copy link
Copy Markdown
Member

Found in production: a scheduler whose planned job key was already running looped once per second — dispatch returned ErrJobExists, which released the scheduler's ownership record and aborted the remaining plan, so the next transition minted a fresh dispatch ID and failed identically. Any scheduled job that outlives one interval (or a key held by a foreign job, e.g. one that was requeued and lost its dispatch identity) never converges, and every job planned after it is starved.

An occupied key already satisfies the transition. A job this scheduler dispatched now keeps its ownership record, so later transitions retry the same exact dispatch instead of minting a new identity; a foreign occupant drops the speculative claim and is retried on the next transition, preserving the invariant that a scheduler never owns or stops a job it did not dispatch. Either way the remaining planned jobs still run.

Tests: TestSchedulerCollisionNeverOwnsForeignJob now asserts convergence (no error, no ownership, later plan entries still dispatched, foreign job untouched by clearJobs) and TestSchedulerKeepsOwnershipWhenItsOwnJobStillRuns pins identity stability across repeated transitions. Full repo -race suite green against live Redis.

A scheduler transition whose planned key is already running had its dispatch
rejected with ErrJobExists, which released the scheduler's ownership record
and aborted the rest of the plan. The next transition then proposed a fresh
dispatch ID and failed identically, so a scheduled job that outlived one
interval — or a key held by a foreign job — produced a permanent
re-dispatch loop and starved every job planned after it.

An occupied key already satisfies the transition. A job this scheduler
dispatched keeps its ownership so later transitions retry the same exact
dispatch instead of minting a new identity; a foreign occupant drops the
speculative claim and is retried next transition, preserving the rule that a
scheduler never owns or stops a job it did not dispatch. Either way the
remaining planned jobs still run.
@raphael
raphael merged commit 576f0a0 into main Jul 26, 2026
5 checks passed
@raphael
raphael deleted the scheduler-occupied-key branch July 26, 2026 03:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant