Repository navigation
Conversation
…ceptor The GlobalPartitionedInterceptor re-routes inbound external messages through Wolverine's routing so they land on the correct internal shard. Previously it built a fresh MessageBus(_runtime) with no inbound envelope, so PropagateHeadersRule.ApplyCorrelation short-circuited (originator.Envelope was null) and the re-published envelope dropped correlation, tenant id, and distributed-trace continuity. Trace context restarted at the interceptor hop and any PropagateIncomingHeadersToOutgoing allowlist was silently ignored for globally-partitioned messages. The interceptor now constructs a per-receive RouteBus seeded with the inbound envelope, copies CorrelationId/TenantId/GroupId via DeliveryOptions, and brackets the publish in an Activity rooted at envelope.ParentId so the re-routed envelope continues the original trace. Custom headers are not copied wholesale — they flow only via PropagateIncomingHeadersToOutgoing, matching cascade semantics. The interceptor ctor is simplified to (IReceiver, IWolverineRuntime); topologies and logger are derived from runtime. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
2 tasks done
Member
|
Using the slightly different #2710, but with attribution |
jeremydmiller
added a commit
that referenced
this pull request
May 8, 2026
….CopyContextCorrelationFrom() Supersedes the implementation in #2709 while keeping the test contract Lyall established (cherry-picked here as the parent commit so attribution is preserved end-to-end). Behavioural shape is identical to Lyall's PR — re-routed envelopes inherit the inbound's correlation, tenant id, and distributed-trace parent — but the field copying is delegated to the existing `Envelope.CopyContextCorrelationFrom` helper. That method was added in GH-2571 / PR #2572 to give the durable scheduled-send unwrap path (`ScheduledSendEnvelopeHandler`) and the in-memory tracked-session replay path (`TrackedSession.ReplayAll`) one canonical place to copy the six context-correlation fields: CorrelationId, ConversationId, TenantId, UserName, ParentId, SagaId The global-partitioning re-route is the same forwarding shape — same logical message, different shard — so it should reuse the same helper rather than re-state the field list inline. This PR adds it as the third caller. Implementation: * `RouteBus` (private subclass of `MessageBus`) still seeds `Envelope = inbound` so `IEnvelopeRule.ApplyCorrelation` consumers like `PropagateHeadersRule` continue to see the originator and honour the `PropagateIncomingHeadersToOutgoing` allowlist. * `RouteBus` overrides `TrackEnvelopeCorrelation` and replaces the base bus's narrower per-field pull-from-bus logic with a single `outbound.CopyContextCorrelationFrom(_inbound)` call. The base copies `CorrelationId` / `TenantId` / `UserName` from the bus's own properties and writes a fresh `ParentId` from `Activity.Current` — both wrong for a forwarded envelope: `ConversationId` would restart, `SagaId` would drop, and the trace would re-root at the interceptor hop instead of continuing the inbound's parent. * The interceptor's `DeliveryOptions` is reduced to just `GroupId`, which is the only piece routing itself needs to read — every context field flows through the bus's overridden tracker. Test coverage: same suite, lifted from #2709 unchanged. The two `ShouldNotContainKey` calls were tweaked to disambiguate Shouldly's `IDictionary` / `IReadOnlyDictionary` overloads (`Envelope.Headers` is a concrete `Dictionary`); behavioural assertions are otherwise verbatim. Tests: full `Runtime.Partitioning` suite green (78/78) on net9.0, including the 16 GP-interceptor cases with the four new context behaviours from #2709. Co-Authored-By: Lyall Guiney <lyall@sportcontext.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The GlobalPartitionedInterceptor re-routes inbound external messages through Wolverine's routing so they land on the correct internal shard. Previously it built a fresh MessageBus(_runtime) with no inbound envelope, so PropagateHeadersRule.ApplyCorrelation short-circuited (originator.Envelope was null) and the re-published envelope dropped correlation, tenant id, and distributed-trace continuity. Trace context restarted at the interceptor hop and any PropagateIncomingHeadersToOutgoing allowlist was silently ignored for globally-partitioned messages.
The interceptor now constructs a per-receive RouteBus seeded with the inbound envelope, copies CorrelationId/TenantId/GroupId via DeliveryOptions, and brackets the publish in an Activity rooted at envelope.ParentId so the re-routed envelope continues the original trace. Custom headers are not copied wholesale — they flow only via PropagateIncomingHeadersToOutgoing, matching cascade semantics. The interceptor ctor is simplified to (IReceiver, IWolverineRuntime); topologies and logger are derived from runtime.