fix(process): reject pending promises when clearing command lane

clearCommandLane() was truncating the queue array without calling
resolve/reject on pending entries, causing never-settling promises
and memory leaks when upstream callers await enqueueCommandInLane().

Splice entries and reject each before clearing so callers can handle
the cancellation gracefully.
This commit is contained in:
Yi LIU
2026-02-14 01:26:05 +08:00
committed by Peter Steinberger
parent f7e2b8ff5f
commit a49dd83b14
2 changed files with 34 additions and 1 deletions

View File

@@ -17,6 +17,7 @@ vi.mock("../logging/diagnostic.js", () => ({
}));
import {
clearCommandLane,
enqueueCommand,
enqueueCommandInLane,
getActiveTaskCount,
@@ -194,4 +195,33 @@ describe("command queue", () => {
resolve2();
await Promise.all([first, second]);
});
it("clearCommandLane rejects pending promises", async () => {
let resolve1!: () => void;
const blocker = new Promise<void>((r) => {
resolve1 = r;
});
// First task blocks the lane.
const first = enqueueCommand(async () => {
await blocker;
return "first";
});
// Second task is queued behind the first.
const second = enqueueCommand(async () => "second");
// Give the first task a tick to start.
await new Promise((r) => setTimeout(r, 5));
const removed = clearCommandLane();
expect(removed).toBe(1); // only the queued (not active) entry
// The queued promise should reject.
await expect(second).rejects.toThrow("Command lane cleared");
// Let the active task finish normally.
resolve1();
await expect(first).resolves.toBe("first");
});
});