mailbox S6: shutdown() in the shim + unit gates; bump wxwidgets
Shim shutdown: dead latch, queue rejection/drop with beacons, pump stops, idempotent. Gates: shim units 11/11, asyncify 9/9, coroutine 39/39, wx modal-heavy 45/45, kicad 6/6 — all on DEFAULT-injected glue (docker postprocess -> setup:kicad now yields scheduler builds without manual conversion). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfxKn5utcntBSnxz4ZnYKs
This commit is contained in:
parent
a17d87a4bd
commit
9bc4da89ff
4 changed files with 92 additions and 1 deletions
|
|
@ -19,12 +19,16 @@ const SHIM_PATH = path.resolve(
|
|||
);
|
||||
|
||||
type SchedulerShape = {
|
||||
mailbox: unknown[];
|
||||
mutatorQueue: unknown[];
|
||||
mutatorsDelivered: number;
|
||||
readyWakes: { deliver: (r: unknown) => void; result: unknown }[];
|
||||
deferredWakes: number;
|
||||
drainedWakes: number;
|
||||
strayWrites: number;
|
||||
dead: boolean;
|
||||
shutdown(reason: string): void;
|
||||
enqueueAfter(fn: number, arg: number, ms: number): void;
|
||||
_openBusy(): boolean;
|
||||
_armMutatorPump(): void;
|
||||
_scheduleWakeDrain(): void;
|
||||
|
|
@ -136,6 +140,43 @@ describe("N5: scheduler shim under flood", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("S6 shutdown: queued mutators reject, messages and wakes drop, pumps stop", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
let busy = true;
|
||||
const S = loadShim({ busy: () => busy });
|
||||
const M = (globalThis as Record<string, unknown>).Module as {
|
||||
kicadCollabApplyItems: (x: number) => Promise<string> | string;
|
||||
};
|
||||
const p = Promise.resolve(M.kicadCollabApplyItems(1));
|
||||
const exP = expect(p).rejects.toThrow("shutdown");
|
||||
S.enqueueAfter(1234, 0, 5);
|
||||
await vi.advanceTimersByTimeAsync(6); // message lands in the mailbox
|
||||
S.readyWakes.push({ deliver: () => undefined, result: 0 });
|
||||
expect(S.mailbox.length).toBe(1);
|
||||
expect(S.mutatorQueue.length).toBe(1);
|
||||
|
||||
S.shutdown("test teardown");
|
||||
await exP;
|
||||
expect(S.mailbox.length).toBe(0);
|
||||
expect(S.mutatorQueue.length).toBe(0);
|
||||
expect(S.readyWakes.length).toBe(0);
|
||||
expect(S.dead).toBe(true);
|
||||
expect(S.state()).toContain("DEAD");
|
||||
|
||||
// Post-shutdown enqueues are dropped, and idempotent shutdown is safe.
|
||||
S.enqueueAfter(1234, 0, 1);
|
||||
await vi.advanceTimersByTimeAsync(5);
|
||||
expect(S.mailbox.length).toBe(0);
|
||||
S.shutdown("again");
|
||||
busy = false;
|
||||
await vi.advanceTimersByTimeAsync(100); // pumps must stay stopped
|
||||
expect(S.mutatorsDelivered).toBe(0);
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it("deferred wakes drain strictly FIFO", async () => {
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in a new issue