Introduction
This sample shows how to use the recoverability error notifications to capture the following:
- When a Immediate Retry occurs.
- When a Delayed Retry occurs.
- When a message fails all retries and is forwarded to the error queue.
Custom Settings in this sample
This sample uses several non-standard settings.
Logging
All errors below Fatal are suppressed to reduce the noise related to raising multiple exceptions
var defaultFactory = LogManager.Use<DefaultFactory>();
defaultFactory.Level(LogLevel.Fatal);
Delayed Retry Time increase
The time to increase changed to 1 second so the wait for all retries to occur is reduced.
var recoverability = endpointConfiguration.Recoverability();
recoverability.Delayed(
customizations: delayed =>
{
delayed.TimeIncrease(TimeSpan.FromSeconds(1));
});
Plugging into the API
The notifications API is exposed as follows.
var endpointConfiguration = new EndpointConfiguration("Samples.Notifications");
SubscribeToNotifications.Subscribe(endpointConfiguration);
public static class SubscribeToNotifications
{
static ILog log = LogManager.GetLogger(typeof(SubscribeToNotifications));
public static void Subscribe(EndpointConfiguration endpointConfiguration)
{
var recoverability = endpointConfiguration.Recoverability();
recoverability.Immediate(settings => settings.OnMessageBeingRetried(Log));
recoverability.Delayed(settings => settings.OnMessageBeingRetried(Log));
recoverability.Failed(settings => settings.OnMessageSentToErrorQueue(Log));
}
static string GetMessageString(ReadOnlyMemory<byte> body)
{
return Encoding.UTF8.GetString(body.ToArray());
}
static Task Log(FailedMessage failed, CancellationToken cancellationToken)
{
log.Fatal($@"Message sent to error queue.
Body:
{GetMessageString(failed.Body)}");
return Task.CompletedTask;
}
static Task Log(DelayedRetryMessage retry, CancellationToken cancellationToken)
{
log.Fatal($@"Message sent to Delayed Retries.
RetryAttempt:{retry.RetryAttempt}
Body:
{GetMessageString(retry.Body)}");
return Task.CompletedTask;
}
static Task Log(ImmediateRetryMessage retry, CancellationToken cancellationToken)
{
log.Fatal($@"Message sent to Immediate Retry.
RetryAttempt:{retry.RetryAttempt}
Body:
{GetMessageString(retry.Body)}");
return Task.CompletedTask;
}
}
Notifications are manipulated at configuration time.
Notifications are executed on the same thread as the NServiceBus pipeline. If long running work needs to be done it should be executed on another thread otherwise the message processing performance can be impacted.
Message Body
Since the message could have failed due to a deserialization exception, it is not possible for the API to provide the instance of the message. For the same reason is it recommended that consumers of this API do not attempt to deserialize the message instance. If the message contents are required for debugging purposes, convert the message body to a string using the .NET Encoding
APIs.