Skip to content

Honouring retries from 429 response #247

@mcquiggd

Description

@mcquiggd

I am attempting to capture a 429 response, and the advised retry interval from the HTTPResponse, as outlined in the blog post here

I am using .Net Core, with version 5.1 (current latest) of Polly.

I have started trying to get a simple HTTPResponse captured, but ultimately I want to use Polly to handle retries for the .Net Core DocumentDB client.

The example code in the blog post is as follows:

var honoursRetryAfter = Policy<HttpResponseMessage>  
  .Handle<HttpException>
  .OrResult(r => statusCodesToRetry.Contains(r.StatusCode)) // detail elided
  .RetryAsync(retryCount: /* your preferred retry count */, 
         sleepDurationProvider: (retryAttempt, context) => 
             context.ContainsKey("RetryAfter") && context["RetryAfter"] != null
             ? (TimeSpan)context["RetryAfter"] 
             : defaultSleepProvider(retryAttempt)  // detail elided
  );

Unfortunately, this particular item seems to be more pseudocode than a usable example - there is no such named parameter as sleepDurationProvider for RetryAsync. So, I have tried WaitAndRetry as follows:

            var honoursRetryAfterAsync = Policy<HttpResponseMessage>
                .Handle<Exception>()
                .OrResult(r => r.StatusCode.ToString().Contains("429"))
                .WaitAndRetryAsync(                    
                    retryCount: 3,
                    sleepDurationProvider: (retryAttempt, context) => context.ContainsKey("RetryAfter") && context["RetryAfter"] != null
                                                                          ? (TimeSpan)context["RetryAfter"]
                                                                          : TimeSpan.FromSeconds(0.5),
                    onRetryAsync: async (message, timespan, retryAttempt, context) => await DoSomething(context["httpClient"]));

However, it is becoming confusing, as there are so many overrides with different signatures, and their availability depends on the complete signature of the complete Policy, and some of the examples in the documentation do not compile. e.g:

Policy
  .HandleResult<HttpResponseMessage>(r => r.StatusCode == 500) // Error - cannot use equality between r.StatusCode and int
  .OrResult<HttpResponseMessage>(r => r.StatusCode == 502) // Error - should not specify <HttpResponseMessage> again

So, I am feeling as If I am just hacking things together in an inappropriate way ;)

I would really appreciate it if someone can point me in the right direction to get this feature working, as intended.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions