Problem
The native runtime package gate runs native-interop-race --batches 100 --width 32 to verify cancellation, result-pool cleanup, and generated interop accounting across four V8 contexts. On a contended macOS hosted runner, the probe rejected otherwise valid calls with:
Generated native interop invocation was rejected: Native interop invocation queue is full
Observed failure on run 34961173025:
- 12,800 intended operations
- 12,672 generated calls
- 12,672 cancellations
- 128 queue-full faults
- all four result/operation pools drained to zero afterward
The native engine, 21 CTests, 150-document/514-subtest required web-platform subset, media profiles, and 55 Avalonia tests had already passed. The failure was in the stress harness pacing.
Root cause
After disposing each batch's managed invokers, the probe slept for a fixed 20 ms and enqueued native-interop-race-barrier.js. TryExecuteScript only accepts that script asynchronously; it does not wait for execution. On a slower runner, cancelled promise work could remain ahead of the barrier, so multiple batches accumulated in the bounded 64-entry native interop queue.
The initial fixture installation had the same asynchronous assumption.
Fix
Draft PR #76 at consolidated commit 41cf43cc34355f9511df94631f49baa87ff8818f uses EngineMetrics.ExecutedScripts as a completion fence:
- Read the current counter.
- Enqueue the fixture or barrier script.
- Poll until
ExecutedScripts advances, with a five-second deadline.
- Start the next batch only after the barrier queued behind the prior interop work has executed.
This preserves the full 100 x 32 x 4 stress workload and the queue bound. It removes wall-clock timing as a correctness condition and still fails on a real worker stall, lost script, interop fault, accounting mismatch, or leaked result/operation slot.
Validation
The benchmark project builds with zero warnings and errors. The complete PR #76 matrix passed:
- hosted macOS, Ubuntu, and Windows builds
- NativeAOT contracts and Linux native contracts
- packaged Linux x64, macOS arm64, and Windows x64 runtimes
- cross-RID candidate and required evidence
- release-package verification
- installed-package consumers on all three RIDs
The NuGet publish and release-commit guard were skipped by design because this is a draft, non-release revision.
Problem
The native runtime package gate runs
native-interop-race --batches 100 --width 32to verify cancellation, result-pool cleanup, and generated interop accounting across four V8 contexts. On a contended macOS hosted runner, the probe rejected otherwise valid calls with:Observed failure on run 34961173025:
The native engine, 21 CTests, 150-document/514-subtest required web-platform subset, media profiles, and 55 Avalonia tests had already passed. The failure was in the stress harness pacing.
Root cause
After disposing each batch's managed invokers, the probe slept for a fixed 20 ms and enqueued
native-interop-race-barrier.js.TryExecuteScriptonly accepts that script asynchronously; it does not wait for execution. On a slower runner, cancelled promise work could remain ahead of the barrier, so multiple batches accumulated in the bounded 64-entry native interop queue.The initial fixture installation had the same asynchronous assumption.
Fix
Draft PR #76 at consolidated commit
41cf43cc34355f9511df94631f49baa87ff8818fusesEngineMetrics.ExecutedScriptsas a completion fence:ExecutedScriptsadvances, with a five-second deadline.This preserves the full 100 x 32 x 4 stress workload and the queue bound. It removes wall-clock timing as a correctness condition and still fails on a real worker stall, lost script, interop fault, accounting mismatch, or leaked result/operation slot.
Validation
The benchmark project builds with zero warnings and errors. The complete PR #76 matrix passed:
The NuGet publish and release-commit guard were skipped by design because this is a draft, non-release revision.