Starting from NServiceBus version 6, the delayed retries policy (formerly known as second level retries policy) has been deprecated in favor of the new custom recoverability policy which allows more control over the recoverability behavior. This documentation shows how the previous delayed retries policies can be implemented with the new recoverability policy.
Delayed retries cannot be used when transport transactions are disabled or delayed delivery is not available. For more information about transport transactions, refer to transport transactions. For more details on the caveats, see the delayed delivery article.
Configuring delayed retries
Common settings
Enabled
: Turns the feature on and off. Default: true.TimeIncrease
: A time span after which the time between retries increases. Default: 10 seconds (00:00:10
).NumberOfRetries
: Number of times delayed retries are performed. Default: 3.
Using app.config
To configure delayed retries, enable its configuration section:
<configSections>
<section name="SecondLevelRetriesConfig"
type="NServiceBus.Config.SecondLevelRetriesConfig, NServiceBus.Core"/>
</configSections>
<SecondLevelRetriesConfig Enabled="true"
TimeIncrease="00:00:10"
NumberOfRetries="3" />
Through IProvideConfiguration
class ProvideConfiguration :
IProvideConfiguration<SecondLevelRetriesConfig>
{
public SecondLevelRetriesConfig GetConfiguration()
{
return new SecondLevelRetriesConfig
{
Enabled = true,
NumberOfRetries = 2,
TimeIncrease = TimeSpan.FromSeconds(10)
};
}
}
Through ConfigurationSource
public class ConfigurationSource :
IConfigurationSource
{
public T GetConfiguration<T>() where T : class, new()
{
if (typeof(T) == typeof(SecondLevelRetriesConfig))
{
var config = new SecondLevelRetriesConfig
{
Enabled = true,
NumberOfRetries = 2,
TimeIncrease = TimeSpan.FromSeconds(10)
};
return config as T;
}
// Respect app.config for other sections not defined in this method
return ConfigurationManager.GetSection(typeof(T).Name) as T;
}
}
busConfiguration.CustomConfigurationSource(new ConfigurationSource());
Disabling through code
busConfiguration.DisableFeature<SecondLevelRetries>();
Custom retry policy
Custom retry logic can be configured via code.
var retriesSettings = busConfiguration.SecondLevelRetries();
retriesSettings.CustomRetryPolicy(MyCustomRetryPolicy);
Simple policy
The following retry policy overrides the default ten second delay interval and sets it to five seconds.
TimeSpan MyCustomRetryPolicy(TransportMessage transportMessage)
{
// retry max 3 times
if (NumberOfRetries(transportMessage) >= 3)
{
// sending back a TimeSpan.MinValue tells the
// SecondLevelRetry not to retry this message
return TimeSpan.MinValue;
}
return TimeSpan.FromSeconds(5);
}
static int NumberOfRetries(TransportMessage transportMessage)
{
var headers = transportMessage.Headers;
if (headers.TryGetValue(Headers.Retries, out var value))
{
return int.Parse(value);
}
return 0;
}
Exception-based policy
Sometimes the number of retries or the delay interval might depend on the error exception thrown. The following retry policy extends the previous one by skipping delayed retries whenever MyBusinessException
has been thrown during incoming message processing.
TimeSpan MyCustomRetryPolicy(TransportMessage transportMessage)
{
if (ExceptionType(transportMessage) == typeof(MyBusinessException).FullName)
{
// Do not retry for MyBusinessException
return TimeSpan.MinValue;
}
if (NumberOfRetries(transportMessage) >= 3)
{
return TimeSpan.MinValue;
}
return TimeSpan.FromSeconds(5);
}
static int NumberOfRetries(TransportMessage transportMessage)
{
var headers = transportMessage.Headers;
if (headers.TryGetValue(Headers.Retries, out var value))
{
return int.Parse(value);
}
return 0;
}
static string ExceptionType(TransportMessage transportMessage)
{
var headers = transportMessage.Headers;
return headers["NServiceBus.ExceptionInfo.ExceptionType"];
}