/** * Idle-preferring worker selection helper. * * Workers run as in-process instances that each poll the DB for jobs. Without * coordination, whichever worker's poll timer fires first claims the next job — * so a busy worker can grab work while an idle sibling sits at 0/n. This helper * implements the "most-free-wins" rule: before claiming, a worker checks its * siblings and yields to one that has STRICTLY more free slots (scoped to * siblings that are available and actually serve the job's role). A 0/n idle * worker therefore always beats a partially-loaded one. * * Returns the index of the idlest qualifying competitor, or -1 when the caller * is already (tied for) the most free and should claim the job itself. */ export interface ClaimCandidate { /** max_concurrency − inflight for this candidate. */ freeSlots: number; /** Running, healthy, enabled — would actually claim if poked. */ availableForClaim: boolean; /** Serves the role of the job about to be claimed. */ servesRole: boolean; } export function pickIdlerIndex( selfFreeSlots: number, candidates: readonly ClaimCandidate[], ): number { let bestIdx = -1; let bestFree = selfFreeSlots; // a competitor must STRICTLY exceed this to win for (let i = 0; i < candidates.length; i++) { const c = candidates[i]; if (!c.availableForClaim || !c.servesRole) continue; if (c.freeSlots > bestFree) { bestIdx = i; bestFree = c.freeSlots; } } return bestIdx; }