Skip to content

Build every outgoing RabbitMQ message in one module: one pure build call per operation owns ids, routing, properties, envelope, retry, fault and reply, and faults and replies get the base properties - #433

Merged
Vulthil merged 1 commit into
mainfrom
refactor/rabbitmq-outgoing-messages
Oct 2, 2026
Merged

Vulthil merged 1 commit into
mainfrom
refactor/rabbitmq-outgoing-messages

Conversation

@Vulthil

@Vulthil Vulthil commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Summary

Every message the RabbitMQ transport writes to the broker is now built in one module. Before, RabbitMqWireMessageBuilder had four small helpers (one took 7 parameters for 2 lines), so the publisher, the send endpoint and the requester each repeated the same sequence by hand, the routing-key rule was written twice, and the consumer worker built its retry, fault and reply messages with their own, slightly different properties.

  • RabbitMqOutgoingMessages (new, internal) has one pure build call per operation — Publish, Send, Request, Retry, Fault, Reply — and does no I/O. It owns:
    • id resolution and the routing-key rule (context key, else the type's formatter, else empty), now written once;
    • the base properties (Type, MessageId, ContentType, Timestamp, a copy of the headers) and the properties per operation (ReplyTo, the AMQP correlation id, persistence, TTL);
    • envelope serialization, the retry headers and TTL, the fault route and the payload as delivered, and the reply route (a request without ReplyTo gets no reply).
  • RabbitMqOutgoingMessage (exchange, routing key, mandatory flag, properties, body) is what every producer publishes; RabbitMqProducedMessage adds the resolved ids and starts the producer activity for publish, send and request.
  • The publisher, the send endpoint, the requester and the consumer worker call the builder, then publish. Each keeps its own channel use and error handling (the publisher throws, the requester returns a Result, the worker publishes through its channel gate). IInternalPublisher takes the built message. RabbitMqWireMessageBuilder is deleted.
  • Wire change (additive): faults gain ContentType and a MessageId of their own; replies gain MessageId (their envelope's) and Timestamp. Nothing in this repository reads these on faults or replies. The fault Type (Fault<…>) and the persistence rules do not change. The messaging docs state the rule.
  • Small tracing difference: a serialization failure now fails before the producer activity starts, so it records no span (before, it ended an unstatused span). The requester still turns it into a Publish failure result.

No public API change.

Verification

  • dotnet build Vulthil.SharedKernel.slnx: 0 warnings, 0 errors.
  • All 18 unit test projects pass on net10.0 and net9.0. Vulthil.Messaging.RabbitMq.Tests has 139 tests. The new RabbitMqOutgoingMessagesTests has 19 cases: 16 new, and the 3 fault-route tests moved there from the worker tests. Each new test compares one row — route, mandatory flag and every property — with the shape its operation must have, without mocks, and checks the body.
  • Vulthil.IntegrationTests (Docker, including the real-broker delayed-retry and consumer-pause tests): 70/70 on net10.0 and net9.0.
  • Aspire MessagingIntegrationTests (real producer and consumer services, including request/reply): 13/13 on net10.0.
  • Break checks (each made tests fail, then reverted):
    • the routing-key formatter ignored: 1 test fails;
    • a publish that is not persistent: 1 test fails;
    • a send that is not mandatory: 1 test fails;
    • a fault without ContentType: 1 test fails;
    • a reply with a fresh MessageId: 1 test fails;
    • a retry that writes into the delivery's own headers: 1 test fails;
    • a request that waits indefinitely but still expires: 2 tests fail.

Backport to v1.0: no

…all per operation owns ids, routing, properties, envelope, retry, fault and reply, and faults and replies get the base properties
@Vulthil
Vulthil merged commit d4b632a into main Oct 2, 2026
7 checks passed
@Vulthil
Vulthil deleted the refactor/rabbitmq-outgoing-messages branch October 2, 2026 14:00
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.

1 participant