Skip to content

Preserve context fields on scheduled sends to non-native transports#2572

Closed
ArieGato wants to merge 1 commit intoJasperFx:mainfrom
ArieGato:fix/preserve-context-on-scheduled-wrap
Closed

Preserve context fields on scheduled sends to non-native transports#2572
ArieGato wants to merge 1 commit intoJasperFx:mainfrom
ArieGato:fix/preserve-context-on-scheduled-wrap

Conversation

@ArieGato
Copy link
Copy Markdown
Contributor

Fixes #2571.

Summary

  • When an envelope is scheduled to a transport without native scheduled-send (RabbitMQ, Kafka, SharedMemory, ...), MessageRoute.ForScheduledSend wraps it and previously eagerly serialized the inner into outer.Data before TrackEnvelopeCorrelation could stamp context fields. The inner therefore arrived on the receive side with TenantId = null, SagaId = null, CorrelationId/UserName unset — breaking multi-tenanted saga timeouts and observability chains.
  • Defers serialization to EnvelopeReaderWriter.Write, which now unwraps model.Message to serialize the inner.
  • Extracts a virtual MessageBus.StampEnvelope with the idempotent context-derived stamps (Source, CorrelationId, TenantId, UserName); MessageContext overrides it to add SagaId. TrackEnvelopeCorrelation calls it on the outer and, when the envelope is a scheduled wrap, also on the inner.

Test plan

  • CoreTests.Runtime.Scheduled.inner_envelope_is_stamped_before_serialization — in-process via SharedMemory wrap path; asserts TenantId, CorrelationId, UserName on the delivered inner.
  • Wolverine.RabbitMQ.Tests.scheduled_saga_timeout_preserves_tenant — end-to-end multi-tenant saga with Marten + RabbitMQ + durable outbox; verifies the handler runs under the original tenant and the saga completes.
  • Full CoreTests suite (1347/1347) passes on net9.0.
  • RabbitMQ suite: new test passes; unrelated DLQ/tenancy failures are pre-existing flakes (reproduce on main, pass in isolation).

When an envelope is scheduled to a transport without native scheduled-send
support (RabbitMQ, Kafka, SharedMemory, ...), MessageRoute wraps it via
ForScheduledSend and the transport ultimately serializes the inner envelope.
Previously context-derived fields (TenantId, SagaId, CorrelationId, UserName)
were only stamped on the outer wrapper, so the inner lost them by the time
it reached the receiving handler.

Extracts a virtual StampEnvelope method on MessageBus containing the
idempotent context-derived stamps and applies it to both the outer envelope
and the inner envelope of a scheduled wrap. MessageContext overrides it to
add SagaId.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jeremydmiller
Copy link
Copy Markdown
Member

Hey, I'm going to want a little more review on this one, so it's not going to make the release this morning

@ArieGato
Copy link
Copy Markdown
Contributor Author

Should I put any effort in this to resolve the merge conflict?

@jeremydmiller
Copy link
Copy Markdown
Member

I took your test, but went a little different way to keep overhead out of the hot path: #2605

@ArieGato
Copy link
Copy Markdown
Contributor Author

Great you fixed it, thnx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Scheduled sends to non-native-scheduling transports lose context fields (TenantId, SagaId, CorrelationId, UserName)

2 participants