This sample shows how to retry a failed message. The sample uses the Learning Transport and a portable version of the Particular Service Platform tools. Installing ServiceControl is not required.
Running the solution
Running the solution starts 3 console windows. Wait a moment until the ServicePulse window opens in the browser.
Sender
The sender is a program that uses NServiceBus to send simple test messages.
2024-09-12 09:38:38.902 INFO Logging to 'C:\Particular\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Sender\bin\Debug\net8.0\' with level Info
2024-09-12 09:38:39.070 INFO Selected active license from C:\ProgramData\ParticularSoftware\license.xml
License Expiration: 2029-10-31
Press 'Enter' to send a new message. Press any other key to finish.
Press Enter in the Sender console window to send one.
Receiver
The receiver reads messages off a queue and processes them. By default, it runs in a fault simulation mode, which causes message processing to fail, including the one that has just been sent.
2024-09-12 09:38:38.826 INFO Logging to 'C:\Particular\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Receiver\bin\Debug\net8.0\' with level Info
2024-09-12 09:38:38.983 INFO Selected active license from C:\ProgramData\ParticularSoftware\license.xml
License Expiration: 2029-10-31
Press 't' to toggle fault mode or `Esc` to stop.
2024-09-12 09:41:32.540 INFO Received message.
2024-09-12 09:41:32.744 ERROR Moving message 'b287b065-1fb1-4fb1-8b71-b1e9007ec40d' to the error queue 'error' because processing failed due to an exception:
System.Exception: Simulated error.
at SimpleMessageHandler.Handle(SimpleMessage message, IMessageHandlerContext context) in C:\Particular\docs.particular.net\samples\servicecontrol\retry-messages\Core_9\Receiver\SimpleMessageHandler.cs:line 19
...
at NServiceBus.LearningTransportMessagePump.ProcessFile(ILearningTransportTransaction transaction, String messageId, CancellationToken messageProcessingCancellationToken) in /_/src/NServiceBus.Core/Transports/Learning/LearningTransportMessagePump.cs:line 340
Exception details:
Message type: SimpleMessage
Handler type: SimpleMessageHandler
Handler start time: 2024-09-12 07:41:32:540082 Z
Handler failure time: 2024-09-12 07:41:32:573794 Z
Handler canceled: False
Message ID: b287b065-1fb1-4fb1-8b71-b1e9007ec40d
Transport message ID: 75fe4ddd-ffde-49b1-a1dc-37c9ab8c40c6
Pipeline canceled: False
Press t to disable the fault simulation mode so that the message is processed correctly once retried.
Exception details:
Message type: SimpleMessage
Handler type: SimpleMessageHandler
Handler start time: 2024-09-12 07:41:32:540082 Z
Handler failure time: 2024-09-12 07:41:32:573794 Z
Handler canceled: False
Message ID: b287b065-1fb1-4fb1-8b71-b1e9007ec40d
Transport message ID: 75fe4ddd-ffde-49b1-a1dc-37c9ab8c40c6
Pipeline canceled: False
t
Fault mode disabled
ServicePulse
Going back to the ServicePulse browser window, there is a notification on the dashboard about one failed message.
Click on the failure symbol to see the datails. You can inspect the message headers as well as the payload.
Now click Request retry
to initiate the message retry process i.e. sending the message back to the receiver's input queue for reprocessing.
Once the process is completed, go back to the Receiver console window.
Receiver
You can now notice that the message has been successfully processed.
Exception details:
Message type: SimpleMessage
Handler type: SimpleMessageHandler
Handler start time: 2024-09-12 07:41:32:540082 Z
Handler failure time: 2024-09-12 07:41:32:573794 Z
Handler canceled: False
Message ID: b287b065-1fb1-4fb1-8b71-b1e9007ec40d
Transport message ID: 75fe4ddd-ffde-49b1-a1dc-37c9ab8c40c6
Pipeline canceled: False
t
Fault mode disabled
2024-09-12 09:44:43.779 INFO Received message.
2024-09-12 09:44:43.781 INFO Successfully processed message.
Code walk-through
For simplicity, both the immediate and the delayed retries are disabled in the sample. As a result, messages are moved to the error queue after a single failed processing attempt:
var recoverability = endpointConfiguration.Recoverability();
recoverability.Delayed(
customizations: retriesSettings =>
{
retriesSettings.NumberOfRetries(0);
});
recoverability.Immediate(
customizations: retriesSettings =>
{
retriesSettings.NumberOfRetries(0);
});
The receiver's failure mode is controlled by the FaultMode
property. When true
processing of SimpleMessage
messages ends with an exception.
logger.LogInformation("Received message.");
if (FaultMode)
{
throw new Exception("Simulated error.");
}
logger.LogInformation("Successfully processed message.");
return Task.CompletedTask;