fix(producer): the stall retry test waits for IO as long as the host needs

This commit is contained in:
Miguel Angel Simon Sierra
2026-11-01 18:33:39 -05:00
parent 13b42bec3c
commit f9418f549f
@@ -235,7 +235,6 @@ const dirs: string[] = [];
const SLOW_TEST_MS = 2_000;
const spent = new Map<string, number>();
let testStarted = 0;
let budgetRanOut = 0;
async function timed<T>(step: string, run: () => Promise<T>): Promise<T> {
const started = performance.now();
try {
@@ -247,7 +246,6 @@ async function timed<T>(step: string, run: () => Promise<T>): Promise<T> {
beforeEach(() => {
spent.clear();
testStarted = performance.now();
budgetRanOut = 0;
capture.scripts = [];
capture.calls = 0;
capture.retriedWithWorkers = [];
@@ -316,27 +314,19 @@ async function settled(outcome: () => unknown): Promise<unknown> {
return outcome();
}
/** Real file IO outlasts any fixed number of turns on a slow host: wait, within a budget, until an attempt is held. */
async function untilHeld(outcome: () => unknown, budget: { ms: number }): Promise<void> {
const started = performance.now();
while (
outcome() === PENDING &&
capture.blocked === 0 &&
performance.now() - started < budget.ms
) {
/** Real file IO takes as long as the host needs: wait, with no wall-clock cap, until an attempt is held. */
async function untilHeld(outcome: () => unknown): Promise<void> {
while (outcome() === PENDING && capture.blocked === 0) {
await new Promise((resolve) => setImmediate(resolve));
}
budget.ms -= performance.now() - started;
if (outcome() === PENDING && capture.blocked === 0) budgetRanOut += 1;
}
/** Jumps fake time to the next timer while the scripted attempt waits, with real IO between steps. */
async function runFor(ms: number, outcome: () => unknown): Promise<void> {
const budget = { ms: 1_000 };
await timed("wait for held", () => untilHeld(outcome, budget));
await timed("wait for held", () => untilHeld(outcome));
for (let elapsed = 0; elapsed < ms && outcome() === PENDING; ) {
await timed("io turns", ioTurns);
await timed("wait for held", () => untilHeld(outcome, budget));
await timed("wait for held", () => untilHeld(outcome));
const before = Date.now();
await timed("advance timers", () => vi.advanceTimersToNextTimerAsync());
const jumped = Date.now() - before;
@@ -436,5 +426,4 @@ it("completes even when the progress sink never drains", async () => {
const outcome = startRender(sinkNeverDrains);
await runFor(120_000, outcome);
expect(await settled(outcome)).toBe("completed");
expect(budgetRanOut).toBe(0);
});