Search code examples
c#.net.net-6.0pollyretry-logic

Polly Retry URL duplicating values


I have configured a Polly IAsyncPolicy using the following code:

IAsyncPolicy retryPolicy = Policy
    .Handle<HttpRequestException>(e => !e.IsBadRequest())
    .WaitAndRetryAsync(
        Backoff.DecorrelatedJitterBackoffV2("00:00:01", 5),
        onRetry: (response, timeSpan, retryCount, context) =>
    {
        if (!context.TryGetLogger(out var logger))
        {
            return;
        }

        logger.LogWarning($"Retrying call {retryCount} with timespan: {timeSpan} due to: {response.Message}");
    });

This is injected into the class as a Singleton and used in the following manner:

var context = new Context($"API-call-{Guid.NewGuid()}", new Dictionary<string, object>
{
    { "logger", _logger },
});

await _resiliencePolicy.ExecuteAsync(async ctx => await _apiClient.Post.Delete(2), _context);

The issue occurs when a retry is made, the original url https://someurl.com/post/2 now becomes https://someurl.com/post/22 (two is repeated) and this keeps happening for each retry. For say the 10th retry the URL would be https://someurl.com/post/222222222

Any ideas would be greatly appreciated.


Solution

  • By definition retry re-executes the provided user delegate / user callback. That means it does not alter anything on the request on your behalf.

    For instance, if you want to change the request url in case of HttpClient request then you have to write a code which fetches the new url each time the user delegate is called by the retry policy. Here you can find an example.

    So, the _apiClient.Post.Delete(2) suspectedly works in a way that it append the provided number at the end of the stored request url.

    Some like this (pseudo-code):

    this.RequestUrl = $"{this.RequestUrl}{deleteParameter}";
    

    In order to fix that (if you can change the underlying code) you have to append the number to the base url to construct the request url (pseudo-code):

    this.RequestUrl = $"{this.BaseUrl}{deleteParameter}";