plugin tests: TestHostJSCancellation's ready-wait cancels 1,000 bootstrap waits rather than 30,000, so it finishes inside its 10 s under a full suite's load

ready-wait failed twice on 10-07 in full `go test -tags nogui ./...` runs on
main ("signal: killed" at 10.00s) and passed alone. The cause is the test's
size, not the host's cancellation. The case runs 30,000 fetch+abort rounds,
each waiting at least one setImmediate turn. That takes ~4s alone, 4.4-8.5s
beside a full go test ./... plus CPU and fresh-script load loops, and more
than 10s when starved (taskpolicy -c background with every core busy: killed
3 of 3). The cost per round stays flat from 5,000 to 120,000 rounds (no growth,
so no leak), and the counts at the end are exact: retainedWaiters 0, one
reaction on the shared ready promise, one drain listener.

Those counts are what catches a leak, and they catch it at any size. With
1,000 rounds, leaving the waiter in readyWaiters fails with retainedWaiters
1000, and a reaction per request on the shared ready promise fails with
retainedReadyReactions 1000.

Before: starved, 3 of 3 runs killed at 10.04-10.26s; -race -count=20 79.9s.
After: starved, 5 of 5 pass (ready-wait 0.6-5.6s, mostly node startup);
-race -count=20 9.9s.
No production code changed.
This commit is contained in:
yetone committed 2026-10-07 04:37:31 +08:00
1 parent d5468283bb
commit d9b2cdc593
1 file changed
+2 -2
+2 -2
View File
@@ -146,7 +146,7 @@ async function main() {
unresolved.then = (...args) => { readyReactions++; return originalThen(...args) }
initialize(unresolved)
run('send({id: 99, result: null})')
for (let iteration = 0; iteration < 30000; iteration++) {
for (let iteration = 0; iteration < 1000; iteration++) {
fetchOne()
abortOne()
await until(idle, 'cancelled bootstrap wait cleans registries')
@@ -156,7 +156,7 @@ async function main() {
assert.equal(stdout.listenerCount('drain'), 1, 'only shared drain listener remains')
const retainedWaiters = run('typeof readyWaiters === "undefined" ? -1 : readyWaiters.size')
const retainedReadyReactions = readyReactions - (run('typeof setReady') === 'function' ? 1 : 0)
console.log(JSON.stringify({ cancellations: 30000, idle: idle(), queued: queued(), readyReactions, retainedReadyReactions, retainedWaiters }))
console.log(JSON.stringify({ cancellations: 1000, idle: idle(), queued: queued(), readyReactions, retainedReadyReactions, retainedWaiters }))
assert.equal(retainedWaiters, 0, 'cancelled bootstrap leaves no retained waiters')
assert.equal(retainedReadyReactions, 0, 'cancelled requests leave no reactions on shared ready')
assert.equal(readyReactions, 1, 'only shared initialization reaction remains')