fix: preserve cancellation when change-time settles

This commit is contained in:
morluto committed 2026-11-11 20:16:24 +08:00
1 parent 5bb34ce522
commit 66e85df5c5
2 files changed
+17 -2

No files matched your search

+14
View File
@@ -271,3 +271,17 @@ it("does not consume Windows limits on other hosts and preserves cancellation du
),
).rejects.toBe(reason);
});
it("preserves cancellation during a Windows read even when the timestamp is stable", async () => {
const controller = new AbortController();
const reason = new Error("cancelled during read");
await expect(
settleChangeTimeBaseline(
async () => {
controller.abort(reason);
return statsAt(1);
},
{ platform: "win32", now: () => 10000, signal: controller.signal },
),
).rejects.toBe(reason);
});
+3 -2
View File
@@ -28,7 +28,8 @@ export interface ChangeTimeSettleSeams {
readonly sleep?: ((delayMs: number) => Promise<void>) | undefined;
/** Launch environment. Omission reads `process.env`. */
readonly environment?:
Readonly<Record<string, string | undefined>> | undefined;
| Readonly<Record<string, string | undefined>>
| undefined;
/** Already resolved budget. Omission parses `environment`. */
readonly limits?: WindowsChangeTimeSettleLimits | undefined;
/** Cancels the wait; the last observation is not returned once aborted. */
@@ -111,10 +112,10 @@ export const settleChangeTimeBaseline = async (
const sleep = seams.sleep ?? defaultSleep;
let observed = await read();
for (let poll = 0; poll < limits.maxPolls; poll += 1) {
throwIfAborted(seams);
if (!changeTimeMayStillDrift(observed, settled)) return observed;
// A settle window is bounded by driftMs, not by the poll budget, so a
// cancelled scope must not keep an inventory waiting it out.
throwIfAborted(seams);
await sleep(limits.pollMs);
throwIfAborted(seams);
observed = await read();