test(perf): fail the J2 quiet wait when a sample stalls past its deadline

waitForJourneyQuiet accepted a sample that returned unchanged after a
stall longer than the timeout as the end of a quiet period, before the
deadline check ran. The deadline is now checked first, so a stalled
sample fails the wait instead of letting the click go ahead unobserved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
4grayandClaude Opus 5.5 committed 2026-09-29 17:42:26 +02:00
1 parent 3d85f4c7d3
commit 6fbb79e66c
2 files changed
+33 -3

No files matched your search

@@ -70,3 +70,30 @@ test('never returns while work stays in flight and fails at the timeout', async
/not-quiet \{"inFlight":1,"requests":1\}/
);
});
test('fails when a sample stalls past the deadline instead of accepting it as quiet', async () => {
let clock = 0;
let samples = 0;
await assert.rejects(
waitForJourneyQuiet<Activity>({
inFlight: (activity) => activity.inFlight,
now: () => clock,
pollMs: 100,
quietMs: 1_000,
sample: async () => {
samples += 1;
// The second sample hangs for 5 s (e.g. behind a busy main
// process) and then reports nothing changed.
if (samples === 2) clock += 5_000;
return { inFlight: 0, requests: 1 };
},
sleep: async (ms) => {
clock += ms;
},
timeoutError: () => new Error('not-quiet-stalled'),
timeoutMs: 3_000,
}),
/not-quiet-stalled/
);
assert.equal(samples, 2);
});
@@ -41,14 +41,17 @@ export async function waitForJourneyQuiet<T>(
const next = await options.sample();
const nextKey = JSON.stringify(next);
const sampledMs = now();
// The deadline is checked first: a sample that stalled past it (for
// example behind a busy main process) must fail the wait, not be
// accepted as the end of a quiet period nobody observed.
if (sampledMs - startedMs > options.timeoutMs) {
throw options.timeoutError(next);
}
if (nextKey !== lastKey || options.inFlight(next) > 0) {
lastKey = nextKey;
quietSinceMs = sampledMs;
} else if (sampledMs - quietSinceMs >= options.quietMs) {
return { sample: next, waitedMs: sampledMs - startedMs };
}
if (sampledMs - startedMs > options.timeoutMs) {
throw options.timeoutError(next);
}
}
}