When an exception occurs you should let the NServiceBus infrastructure handle it (as described here).
It will retry the message a configurable number of times, and if still doesn't work, send it to the error queue.
Second Level Retries (SLR) introduces another level to that.
When using SLR, the message that caused the exception will be, as before, instantly retried, but instead of being sent to the error queue, it will be sent to a retries queue.
SLR will then pick up the message, and defer it, by default first for 10 seconds, then 20 and last 30 seconds, and have it sent back to the original worker queue.
Lets say that you are, within your handler, making a call to an web service and that service is down for 5 seconds just when you are making that call.
Without SLR, the message should have been retried instantly and sent to the error queue.
With SLR, the message will be instantly retried, deferred for 10 seconds, and then retried again.
This time the web service could be up and running, and the message is processed just fine.
Configuration
App.config
To configure Second Level Retries you could enable its configuration section.
<SecondLevelRetriesConfigEnabled="true" TimeIncrease ="00:00:10" NumberOfRetries="3" />
| Enabled | As expected, this turns this feature on and off. By default it’s on. |
| TimeIncrease | A time span by which the time between retries will increase. By default, it’s “00:00:10”. |
| NumberOfRetries | How many times will the SLR kick in? Three by default. |
Fluent configuration API
To disable the SLR feature you could add this to your configuration:
Configure.Instance.DisableSecondLevelRetries();
Code
To change the time between retries and/or number of retires you have a couple of different options in code.
The class SecondLevelRetries exposes a static Function called RetryPolicy and gives you the TransportMessage as an argument.
By altering this you could pretty much implement what ever retry policy you want.
SecondLevelRetries expects a TimeSpan from the policy, and if greater than TimeSpan.Zero it will defer the message using that time span.
The default policy is implemented in the class DefaultRetryPolicy.
That class exposes NumberOfRetries and TimeIncrease as statics so you could easily modify those values.
Working Sample
In the ErrorHandling sample there are two endpoints, one with SLR enabled and the other with it disabled.
When you run the sample, you should start them using Ctrl+F5 (start without debugging), press the letter “S” in both windows at the same time and watch the different outputs.
Both endpoint executes the same code.
