Configure delayed retries

Component: NServiceBus | Nuget: NServiceBus (Version: 5.x)
Starting from NServiceBus Version 6 Delayed Retries Policy (formerly known as Second Level Retries Policy) has been deprecated in favor of the new custom Recoverability policy which allows much more control over the Recoverability behavior. This documentation shows how 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 transaction. For more details on the caveats, see: 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:

Edit
<configSections>
  <section name="SecondLevelRetriesConfig"
           type="NServiceBus.Config.SecondLevelRetriesConfig, NServiceBus.Core"/>
  </configSections>
<SecondLevelRetriesConfig Enabled="true"
                          TimeIncrease="00:00:10"
                          NumberOfRetries="3" />

Through IProvideConfiguration

Edit
class ProvideConfiguration :
    IProvideConfiguration<SecondLevelRetriesConfig>
{
    public SecondLevelRetriesConfig GetConfiguration()
    {
        return new SecondLevelRetriesConfig
        {
            Enabled = true,
            NumberOfRetries = 2,
            TimeIncrease = TimeSpan.FromSeconds(10)
        };
    }
}

Through ConfigurationSource

Edit
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;
    }
}
Edit
busConfiguration.CustomConfigurationSource(new ConfigurationSource());

Disabling through code

Edit
busConfiguration.DisableFeature<SecondLevelRetries>();

Custom Retry Policy

Custom retry logic can be configured via code.

Edit
var retriesSettings = busConfiguration.SecondLevelRetries();
retriesSettings.CustomRetryPolicy(MyCustomRetryPolicy);

Simple Policy

The following retry policy overrides default 10 seconds delay interval and sets it to 5 seconds.

Edit
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)
{
    string value;
    var headers = transportMessage.Headers;
    if (headers.TryGetValue(Headers.Retries, out 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.

Edit
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)
{
    string value;
    var headers = transportMessage.Headers;
    if (headers.TryGetValue(Headers.Retries, out value))
    {
        return int.Parse(value);
    }
    return 0;
}
static string ExceptionType(TransportMessage transportMessage)
{
    var headers = transportMessage.Headers;
    return headers["NServiceBus.ExceptionInfo.ExceptionType"];
}

Samples


Last modified