infuerno.github.io

Pluralsight: Polly Fault Tolerant Web Service Requests

Learning the Basics of the Polly Framework

Resilience strategies

Retry Policy

There are 2 parts: handler part - what to check for and the behaviour part - what to do if the criteria is met. A delegate can also be called prior to each retry.

NOTE: not recommended to instantiate in the constructor of the controller… Better ways to share across controllers and across projects.

readonly RetryPolicy<HttpResponseMessage> _httpRetryPolicy;

public CatalogController()
{
    _httpRetryPolicy = Policy.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode).RetryAsync(3, onRetry: (response, timespan) =>
    {
        if (response.Result.StatusCode == HttpStatusCode.Unauthorized)
        {
            PerformReauthorisaction();
        }
    });
}

public Task<IActionResult> GetOrders()
{
    // calling the remote service
    var response = await _httpRetryPolicy.ExecuteAsync(() => _httpClient.GetAsync(_endpoint));
}

NOTE: The IAsyncPolicy is useful for unit testing, but otherwise the concrete types are simpler for demonstration purposes

Wait and Retry Policy

Wait before the next retry and also allow increasing the backoff between each subsequent request e.g. Ethernet uses an exponential backoff when collisions occur.

.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)/2))

Can additionally add jitter i.e. randomness so that not all services are backing off and retrying at exactly the same time

Fallback

Additionally declare a fallback policy and a meaningful default which the policy will return. Then wrap the currently wrapped call again.

var response = await _httpFallbackPolicy.ExecuteAsync(() => _httpRetryPolicy.ExecuteAsync(() => _httpClient.GetAsync(_endpoint)));