maestro/src/worker/idle-routing.ts
oss-sync d95267c4b0
Some checks failed
CI / build-and-test (push) Has been cancelled
sync: update from private repo (6be06e0)
2026-06-10 01:00:05 +00:00

40 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 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;
}