unsafePtr
unsafePtr

Reputation: 1773

What's alternative of HttpPolicyExtensions.HandleTransientHttpError in new Polly version?

I am trying to upgrade Polly to v8, re-writing policies to utilize new ResiliencePipiline. At couple of places I am using HttpPolicyExtensions.HandleTransientHttpError()

 HttpPolicyExtensions
                .HandleTransientHttpError()
                .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

Looking at the source code I've endup with something like this:

    new ResiliencePipelineBuilder<HttpResponseMessage>()
        .AddRetry(
            new RetryStrategyOptions<HttpResponseMessage>()
            {
                ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
                    .Handle<HttpRequestException>()
                    .HandleResult(response => response.StatusCode >= HttpStatusCode.InternalServerError || response.StatusCode == HttpStatusCode.RequestTimeout),
                MaxRetryAttempts = 3,
                DelayGenerator = static opt => ValueTask.FromResult((TimeSpan?)TimeSpan.FromSeconds(Math.Pow(2, opt.AttemptNumber))),
            })
        .Build();

Upvotes: 1

Views: 1197

Answers (1)

Peter Csala
Peter Csala

Reputation: 22829

Yes, that looks good. If you want to have a bit more performant version then you can use switch expression instead of PredicateBuilder

var options = new RetryStrategyOptions<HttpResponseMessage>
{
    ShouldHandle = static args => args.Outcome switch
    {
        { Exception: HttpRequestException } => PredicateResult.True(),
        { Result.StatusCode: HttpStatusCode.RequestTimeout} => PredicateResult.True(),
        { Result.StatusCode: >= HttpStatusCode.InternalServerError } => PredicateResult.True(),
        _ => PredicateResult.False()
    }
};

Please also note here the usage of static anonymous functions.


Update #1

This could be easily extracted into a util method to embrace reusablity.

public static class PollyUtils
{
  public static ValueTask<bool> HandleTransientHttpError(
    Outcome<HttpResponseMessage> outcome)
    => outcome switch
    {
        { Exception: HttpRequestException } => PredicateResult.True(),
        { Result.StatusCode: HttpStatusCode.RequestTimeout} => PredicateResult.True(),
        { Result.StatusCode: >= HttpStatusCode.InternalServerError } => PredicateResult.True(),
        _ => PredicateResult.False()
    };
}

Upvotes: 2

Related Questions