0

I am getting an error "The request message was already sent. Cannot send the same request message multiple times" for multiple retries of the same request. So, as far as I know, I need to recreate a new HttpRequestMessage for the second retry. Is there a way to know the retry iteration number in the retryPolicy.Execute() sothat I can clone the HttpRequestMessage for second retry empty?

    using Polly; 
    using Polly.Retry;

    namespace RetryLogic {
        public class HttpFactory
        {
            private static readonly TimeSpan defaultTimeoutInMinutes = TimeSpan.FromMinutes(5);
            private static readonly RetryPolicy<HttpResponseMessage> retryPolicy;
            private static readonly HttpClient client;

            static HttpFactory()
            {
                retryPolicy = Policy
                    .Handle<Exception>()
                    .OrResult<HttpResponseMessage>(resp => resp.StatusCode == HttpStatusCode.GatewayTimeout
                                                           || resp.StatusCode == HttpStatusCode.ServiceUnavailable
                                                           || resp.StatusCode == (HttpStatusCode)550)
                    .WaitAndRetry(1, GetRetryDelay);
                var handler = new HttpClientHandler
                {
                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
                };
                client = new HttpClient(handler)
                {
                    Timeout = defaultTimeoutInMinutes
                };
            }

            public static HttpRequestMessage CreateRequest(HttpMethod method, string pathAndQuery, NameValueCollection headers, Stream requestBody)
            {
                HttpRequestMessage request = new HttpRequestMessage(method, pathAndQuery);
                if (requestBody != null)
                {
                    request.Content = new StreamContent(requestBody);
                    request.Headers.TransferEncodingChunked = true;
                }
                return AddRequestHeaders(request, headers);
            }

            public static HttpResponseMessage MakeRequest(HttpRequestMessage request, ILoggerFactory factory, List<HttpOptions> httpOptions = null)
            {
                return retryPolicy.Execute(() =>
                {
// How to know the retry iteration count here?
                    HttpCompletionOption completionOption = HttpCompletionOption.ResponseContentRead;
                    if (httpOptions != null)
                    {
                        foreach (HttpOptions httpOption in httpOptions)
                        {
                            switch (httpOption)
                            {
                                case HttpOptions.SkipReadingResponseContent:
                                    completionOption = HttpCompletionOption.ResponseHeadersRead;
                                    break;
                                case HttpOptions.TransferChunkEncodedRequest:
                                    client.DefaultRequestHeaders.TransferEncodingChunked = true;
                                    break;
                            }
                        }
                    }

                    HttpResponseMessage response = client.SendAsync(request, completionOption).Result;


                    return response;
                });
            }

        }

        public enum HttpOptions
        {
            SkipReadingResponseContent,
            TransferChunkEncodedRequest
        } }
SaiGiridhar
  • 886
  • 1
  • 13
  • 28
  • 1
    There's not an out-of-box way that Polly provides the executed delegate with the try number. You can manually track it yourself with a simple closure, as discussed [here](https://github.com/App-vNext/Polly/issues/380) – mountain traveller Apr 23 '18 at 21:51
  • Thanks. I thought Polly must be providing a way to know the iteration easily instead of using a variable with closure. – SaiGiridhar Apr 24 '18 at 02:37
  • The try number is supplied to other aspects of the retry policy such as the `onRetry` or `onRetryAsync` policy hooks. Supplying extra inputs (without closure) to the code executed through the policy is a generalised problem across all policy types. Polly v6 intends to address this by allowing overloads such as .`Execute(Func func)` (with all Polly's usual additional variants with `CancellationToken` and other current input parameters). – mountain traveller Apr 24 '18 at 05:51

1 Answers1

0

Retry Polly is not providing any inbuilt functionality to know the iteration number.

int iterationNumber = 0;
policy.Execute(() => { 
   iterationNumber++;
   //  ... 
} );
SaiGiridhar
  • 886
  • 1
  • 13
  • 28