Add test demonstrating RabbitMQ DLQ replay bug #1593
Merged
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.
Bug: RabbitMQ DLQ Replay Not Working with SQL Server Persistence
Summary
When using RabbitMQ transport with SQL Server persistence and
DeadLetterQueueMode.WolverineStorage
, replaying messages from the Dead Letter Queue (DLQ) does not work. Messages are successfully moved from the DLQ to the Incoming table, but they are never processed by the handler.Root Cause
The issue is in the
MarkReceived
method insrc/Wolverine/Envelope.Internals.cs
(lines 140-145). When a message is initially received by a RabbitMQ listener, theDestination
property is set to the consumer-specific address (e.g.,rabbitmq://queue/myqueue?consumer=123
) instead of the base queue address (e.g.,rabbitmq://queue/myqueue
).Later, when the message is moved from the DLQ back to the Incoming table via
MoveReplayableErrorMessagesToIncomingOperation
, the originalReceivedAt
value (which contains the?consumer=
parameter) is preserved. However, theDurableReceiver
looks for messages withReceivedAt
matching the base queue address, causing a mismatch.Technical Details
Current Behavior
ReceivedAt = "rabbitmq://queue/myqueue?consumer=123"
ReceivedAt
valueDurableReceiver
queries for messages withReceivedAt = "rabbitmq://queue/myqueue"
(base address)Expected Behavior
ReceivedAt = "rabbitmq://queue/myqueue"
(base address)ReceivedAt
valueDurableReceiver
queries for messages withReceivedAt = "rabbitmq://queue/myqueue"
(base address)Evidence
Test Case
Created isolated test
src/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Bugs/Bug_ReplayDeadLetterQueue.cs
that demonstrates the issue for both durable and non-durable RabbitMQ queues.Test Output
The
ReceivedAt
value contains the?consumer=
parameter, preventing theDurableReceiver
from finding the message.Code Location
The bug is in
src/Wolverine/Envelope.Internals.cs
:Proposed Fix
Modify the
MarkReceived
method to always use the base address for RabbitMQ listeners:Impact
DeadLetterQueueMode.WolverineStorage
Related Files
src/Wolverine/Envelope.Internals.cs
src/Transports/RabbitMQ/Wolverine.RabbitMQ/Internal/RabbitMqListener.cs
- Defines Address vs ConsumerAddresssrc/Transports/RabbitMQ/Wolverine.RabbitMQ.Tests/Bugs/Bug_ReplayDeadLetterQueue.cs
- Test case demonstrating the issuesrc/Persistence/Wolverine.RDBMS/Durability/MoveReplayableErrorMessagesToIncomingOperation.cs
- Operation that moves messages from DLQ to Incoming