sync: update from private repo (6be06e0)
CI / build-and-test (push) Has been cancelled

This commit is contained in:
oss-sync
2026-06-10 01:00:05 +00:00
parent 5c3d7bb5c4
commit d95267c4b0
8 changed files with 223 additions and 7 deletions
+44
View File
@@ -0,0 +1,44 @@
import { describe, it, expect } from 'vitest';
import { pickIdlerIndex, type ClaimCandidate } from './idle-routing.js';
const c = (freeSlots: number, opts: Partial<ClaimCandidate> = {}): ClaimCandidate => ({
freeSlots,
availableForClaim: opts.availableForClaim ?? true,
servesRole: opts.servesRole ?? true,
});
describe('pickIdlerIndex (most-free-wins)', () => {
it('returns -1 when there are no siblings', () => {
expect(pickIdlerIndex(0, [])).toBe(-1);
});
it('yields to a strictly-idler sibling (0/n beats a loaded worker)', () => {
// self has 0 free (fully loaded); sibling has 4 free.
expect(pickIdlerIndex(0, [c(4)])).toBe(0);
});
it('does not yield on a tie (claims itself)', () => {
expect(pickIdlerIndex(2, [c(2), c(2)])).toBe(-1);
});
it('does not yield when the caller is the most free', () => {
expect(pickIdlerIndex(4, [c(1), c(3)])).toBe(-1);
});
it('picks the idlest among several stricter competitors', () => {
expect(pickIdlerIndex(1, [c(2), c(5), c(3)])).toBe(1); // 5 free wins
});
it('ignores siblings that do not serve the role', () => {
expect(pickIdlerIndex(0, [c(8, { servesRole: false })])).toBe(-1);
});
it('ignores unavailable (unhealthy/stopped) siblings', () => {
expect(pickIdlerIndex(0, [c(8, { availableForClaim: false })])).toBe(-1);
});
it('skips a non-serving idler but still yields to a serving one', () => {
// idx0: very idle but wrong role; idx1: idle and serves → pick idx1.
expect(pickIdlerIndex(0, [c(9, { servesRole: false }), c(3)])).toBe(1);
});
});
+39
View File
@@ -0,0 +1,39 @@
/**
* 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;
}