Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I handle backoff or "Wait and Retry" logic in a C# application when an exception occurs?

I am reading from a REST service and need to handle "Wait and retry" for a heavily used service that will give me an error:

Too many queries per second

or

Server Busy

Generally speaking, since I have many REST services to call, how can I generically handle backoff logic that would occur when an exception occurs?

Is there any framework that has this built in? I'm just looking to write clean code that doesn't worry too much about plumbing and infrastructure.

like image 825
makerofthings7 Avatar asked Oct 15 '13 22:10

makerofthings7


People also ask

How does Polly retry work?

With Polly, you can define a Retry policy with the number of retries, the exponential backoff configuration, and the actions to take when there's an HTTP exception, such as logging the error. In this case, the policy is configured to try six times with an exponential retry, starting at two seconds.

What is the name of the Microsoft retry framework?

Microsoft Entity Framework provides facilities for retrying database operations.

How do you write retry logic in Java?

A simple solution to implement retry logic in Java is to write your code inside a for loop that executes the specified number of times (the maximum retry value).


1 Answers

You can wrap the attempt up within a method that handles the retry logic for you. For example, if you're using WebClient's async methods:

public async Task<T> RetryQuery<T>(Func<Task<T>> operation, int numberOfAttempts, int msecsBetweenRetries = 500)
{
     while (numberOfAttempts > 0)
     {
          try
          {
               T value = await operation();
               return value;
          }
          catch
          {
                // Failed case - retry
                --numberOfAttempts;                   
          }

          await Task.Delay(msecsBetweenRetries);
     }

     throw new ApplicationException("Operation failed repeatedly");
}

You could then use this via:

// Try 3 times with 500 ms wait times in between
string result = await RetryQuery(async () => webClient.DownloadStringTaskAsync(url), 3);
like image 114
Reed Copsey Avatar answered Sep 22 '22 00:09

Reed Copsey