Isolate retry span captures from global tracing registration
The gRPC retry capture could observe zero or one attempt in a parallel suite while passing alone. A thread without a subscriber could register the shared RPC callsite while tracing-core's single-dispatcher optimization was active, caching it as disabled despite another thread owning a capture subscriber.
Both retry tests now retain a second dispatcher for their entire capture lifetime and run their assertions in isolated child processes. Captures remain per test and per future; no global subscriber or serialization is added. A deterministic regression registers the real unary RPC callsite without a subscriber before running the captured retry. Its negative control removes the second dispatcher and must lose both spans.
Decisions
- Fix the test capture lifetime rather than alter RPC execution, tracing filters, retry behavior or assertions. The existing exact attempt and outcome assertions remain intact.
- Exercise the real tracing dependency in a fresh child process to control its process-global first-registration state. The failing schedule is deterministic, not a stress run; the negative control must fail the specific two-span assertion with zero captured spans. No production synchronization or parser changes are made.
- Isolate the original retry assertions too: another test may already be inside the single-dispatcher registration path when a capture starts. Thread-local dispatch alone cannot fence that in-flight global registration. The parent requires the child to report exactly one passing test; a successful empty test selection cannot pass validation. The concurrent test still interleaves its two independent captures inside that process.
- The extra dispatcher is a test-local
NoSubscriberinstance. Keeping both live forces callsite registration to consider the registered capture instead of the unrelated registering thread's default subscriber. Each capture still owns a separate registry and collector.
Validation
- Linux through
bs.ps1: all 14 gRPC tests pass in 0.30 s (0.318 s process time), including both retry tests, the deterministic first-registration regression and its negative control. Build log:/home/var/log/buildbox/2026-10-16T093311918Z-3327150.log. - Windows
lb.ps1 cargo check --locked -p acyclic-stream --features local,http --lib --testspasses in 7.23 s.
This isolates the span-capture failure found while validating #644. No latency threshold, connection invariant or retry assertion is weakened.
Summary by cubic
Fixes the gRPC retry span capture tests so they no longer observe zero or one attempt in a parallel suite. tracing-core's single-dispatcher fast path could cache the shared RPC callsite as disabled when a thread without a subscriber registered it first.
- Both retry tests now run their assertions in isolated child processes and keep a second test-local dispatcher alive for the entire capture lifetime.
- A deterministic regression registers the real unary RPC callsite without a subscriber before the captured retry; its negative control drops the second dispatcher and must fail with zero spans.
- The concurrent retry test still runs its two independent captures in the same process, each with its own registry and collector.
- No production code, retry behavior, or assertions changed; only the test capture infrastructure.