Polly is a great library allowing us to add policies such as retry, circuit breaker, timeout, etc. to our HttpClient.
These are the policies I used in my project and how to add them to HttpClient
public class PollyPolicies
{
private static readonly HttpStatusCode[] httpStatusCodesWorthRetrying = new[] {
HttpStatusCode.BadGateway, // 502
HttpStatusCode.ServiceUnavailable, // 503
HttpStatusCode.GatewayTimeout // 504
};
public RetryPolicy<HttpResponseMessage> RetryPolicy => Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => (int)r.StatusCode > (int)HttpStatusCode.InternalServerError || r.StatusCode == HttpStatusCode.RequestTimeout)
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5)
});
public RetryPolicy<HttpResponseMessage> PostRetryPolicy => Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5)
});
public CircuitBreakerPolicy<HttpResponseMessage> CircuitBreakerPolicy => Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => (int) r.StatusCode > (int) HttpStatusCode.InternalServerError || r.StatusCode == HttpStatusCode.RequestTimeout)
.AdvancedCircuitBreakerAsync(
failureThreshold: 0.5, // Break on >=50% actions result in handled exceptions.
samplingDuration: TimeSpan.FromMinutes(1),
minimumThroughput: 30,
durationOfBreak: TimeSpan.FromSeconds(30)
);
public TimeoutPolicy<HttpResponseMessage> TimeoutPolicy => Policy.TimeoutAsync<HttpResponseMessage>(30);
}
RetryPolicy
This policy is for GET requests. We only want to retry if HTTP status code is request timeout or any code higher than internal server error 500. This policy will retry 3 times. It waits for 1 second for the retry, then 3 seconds for the second retry and 5 seconds for the final retry.
PostRetryPolicy
This policy is for POST requests. We only want to retry if HTTP status code is bad gate, service unavailable or gateway timeout. This policy will retry 3 times. It waits for 1 second for the retry, then 3 seconds for the second retry and 5 seconds for the final retry.
CircuitBreakerPolicy
This policy blocks the executions for 30 seconds if the error code is internal server error or request timeout, failed 50% of the requests within 1 minute for the minimum of 30 requests.
TimeoutPolicy
This one is straightforward. The request will timeout after 30 seconds.
To add those policies to the HttpClient, do the following.
var policies = new PollyPolicies();
services.AddHttpClient("SampleClientName", client =>
{
client.BaseAddress = new Uri("some url");
})
.AddPolicyHandler(request => request.Method == HttpMethod.Get ? policies.RetryPolicy : policies.PostRetryPolicy)
.AddPolicyHandler(policies.TimeoutPolicy)
.AddPolicyHandler(policies.CircuitBreakerPolicy);