Implementing a Custom Retry Strategy

Retired Content

This content and the technology described is outdated and is no longer being maintained. For more information, see Transient Fault Handling.

patterns & practices Developer Center

On this page:
Implementing the Custom Retry Strategy | Adding Design-time Support to Your Custom Retry Strategy

To implement a custom retry strategy, you must perform two tasks. First, you must implement your retry strategy by extending the abstract RetryStrategy class. Second, you must add configuration support if you want to use your custom strategy in the application configuration.

Implementing the Custom Retry Strategy

Typically, you provide a set of constructors that initialize your retry strategy with the required parameters. You must also override the GetShouldRetry method.

The following code sample shows a fixed interval retry policy that applies some random variation to the retry intervals as an example implementation. This retry policy uses two parameters: a retry count and a retry interval.

namespace CustomStrategy
{
    using System;
    using System.Collections.Specialized;
    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
    using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.Configuration;
    using Microsoft.Practices.TransientFaultHandling;

    [ConfigurationElementType(typeof(CustomRetryStrategyData))]
    public class RandomizedInterval : RetryStrategy
    {
        private readonly int retryCount;
        private readonly TimeSpan retryInterval;

        public RandomizedInterval(string name, bool firstFastRetry, 
                                  NameValueCollection attributes)
            : base(name, firstFastRetry)
        {
            this.retryCount = int.Parse(attributes["retryCount"]);
            this.retryInterval = TimeSpan.Parse(attributes["retryInterval"]);
        }

        public override ShouldRetry GetShouldRetry()
        {
            if (this.retryCount == 0)
            {
                return delegate(int currentRetryCount, Exception lastException, 
                                out TimeSpan interval)
                {
                    interval = TimeSpan.Zero;
                    return false;
                };
            }

            return delegate(int currentRetryCount, Exception lastException, 
                            out TimeSpan interval)
            {
                if (currentRetryCount < this.retryCount)
                {
                    var random = new Random();
                    interval = TimeSpan.FromMilliseconds(random.Next(
                      (int)(this.retryInterval.TotalMilliseconds * 0.8), 
                      (int)(this.retryInterval.TotalMilliseconds * 1.2)));
                    return true;
                }

                interval = TimeSpan.Zero;
                return false;
            };
        }
    }
}

The GetShouldRetry method returns a delegate of type ShouldRetry. The following snippet shows the definition of this delegate.

public delegate bool ShouldRetry(
  int retryCount, Exception lastException, out TimeSpan delay);

Note

Custom retry strategy implementations must be stateless.

A custom retry strategy must have a constructor that takes the three parameters shown in the sample and invokes the base class constructor as shown in the sample.

Adding Design-time Support to Your Custom Retry Strategy

To enable design-time support for your custom retry strategy, you should add the ConfigurationElementType attribute to the class that implements the retry strategy, as shown in the following code snippet.

...
using Microsoft.Practices.TransientFaultHandling;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.TransientFaultHandling.Configuration;
...

[ConfigurationElementType(typeof (CustomRetryStrategyData))]
public class MyRetryStrategy : RetryStrategy
{
    ...
        public RandomizedInterval(string name, bool firstFastRetry, 
                                  NameValueCollection attributes)
            : base(name, firstFastRetry)
        {
            this.retryCount = int.Parse(attributes["retryCount"]);
            this.retryInterval = TimeSpan.Parse(attributes["retryInterval"]);
        }
    ...
}

The snippet also shows how to access the parameters that the user sets in the Enterprise Library configuration tool when they are configuring the retry strategy.

Hh680943.50B1E1DB849FD66C61BB69D136FF9898(en-us,PandP.50).png

Note

You must also add a reference to System.Configuration in your project.

For information about how to configure your custom retry strategy with the Enterprise Library configuration tool, see the topic "Entering Configuration Information."

Next Topic | Previous Topic | Home

Last built: June 7, 2012