Default request-reply to Direct mode#1182
Conversation
Flip the NatsOpts.RequestReplyMode default from SharedInbox to Direct. Direct skips per-request subscription setup and channel-based delivery, correlating replies through the connection's inbox subscription instead. Direct mode previously ignored ThrowIfNoResponders and always returned the 503 sentinel as a message. Make it honor the flag so RequestAsync behaves the same in both modes. The JetStream publish and API paths inspect the sentinel themselves to retry, so they now opt out with ThrowIfNoResponders=false, matching the shared-inbox path. Tests that assert exact wire frames, subscription sids, or active subscription counts are pinned to SharedInbox: Direct opens an inbox subscription at connect, which shifts those values.
|
Claude finished @mtmk's task in 4m 15s —— View job PR Review: Default request-reply to Direct mode
SummaryThe change is correct and well-structured. The core logic, JetStream opt-outs, and test fixups all look sound. Two minor issues flagged as inline comments: Correctness
Test fixups All protocol-frame-counting tests that assert specific SUB/SID sequences now force Test duplication (see inline): Breaking change note: the default flip from |
Honoring ThrowIfNoResponders in Direct mode (previous commit) changed no-responders from "return a message" to "throw" for callers that had intentionally selected Direct. Record whether Direct was set explicitly (vs inherited as the new default) and default such requests to not throw, restoring their pre-3.x behavior. Default and SharedInbox connections keep throwing. The flag is captured in the RequestReplyMode init accessor; the field initializer bypasses it, so an unset mode is treated as the throwing default. RequestManyAsync always uses the shared inbox path and is scoped out of the opt-out. A per-call NatsSubOpts.ThrowIfNoResponders still wins.
MaxParallelThreads was 1.0x (one thread per core), so collections ran concurrently. Suites that assert on process-global state, notably the OpenTelemetry tests whose ActivityListener and MeterListener observe every NATS.Net activity and measurement in the process, then see another collection's activities and counters and fail with false positives. Defaulting request-reply to Direct made this worse by routing JetStream publish through the instrumented RequestAsync path. Run collections serially across all test projects.
Flip the default request-reply mode to Direct for single-reply requests. Direct avoids per-request subscription setup and channel delivery, correlating replies through the connection's inbox subscription. Direct now honors ThrowIfNoResponders so RequestAsync behaves the same in both modes; the JetStream publish and API paths handle the no-responders sentinel themselves and opt out of the throw.
Fixes #1155