From eb48f4b5bda7d842e61d0fc053d8ad3317c06df0 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Fri, 25 Sep 2026 05:33:16 -0700 Subject: [PATCH] test(signals): settle each spawn task before the next in the retention test Spawning 10000 tasks at once grew the task set through several rehashes. JSC leaves an obsolete table's keys in place after a rehash, so a stale conservative stack word pointing at one kept ~8191 dead promises alive, failing intermittently on arm64 CI. Co-Authored-By: Claude Opus 5.5 --- js/signals/src/index.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/js/signals/src/index.test.ts b/js/signals/src/index.test.ts index 8491741c57..c9d92827e2 100644 --- a/js/signals/src/index.test.ts +++ b/js/signals/src/index.test.ts @@ -1209,9 +1209,14 @@ describe("spawn retention", () => { return heapStats().objectTypeCounts.Promise ?? 0; }; + // Settle each task before the next, like a per-group spawn. Spawning all at once would grow + // the task set through rehashes, and JSC leaves the old tables' keys in place: a stale + // conservative stack word pointing at one keeps ~8k dead promises alive. const before = promises(); - for (let i = 0; i < 10000; i++) effect.spawn(async () => {}); - await settle(); + for (let i = 0; i < 10000; i++) { + effect.spawn(async () => {}); + await settle(); + } expect(promises() - before).toBeLessThan(100); effect.close(); });