Как узнать номер повторной итерации в retryPolicy.excute()

Я получаю сообщение об ошибке «Сообщение с запросом уже отправлено. Невозможно отправить одно и то же сообщение с запросом несколько раз» при нескольких повторных попытках одного и того же запроса. Итак, насколько я знаю, мне нужно воссоздать новый HttpRequestMessage для второй попытки. Есть ли способ узнать номер итерации повторной попытки в retryPolicy.Execute(), чтобы я мог клонировать HttpRequestMessage для второй пустой повторной попытки?

    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
        } }

person SaiGiridhar    schedule 23.04.2018    source источник
comment
Не существует стандартного способа, с помощью которого Полли предоставляет исполняемому делегату номер попытки. Вы можете вручную отслеживать его с помощью простого замыкания, как описано здесь   -  person mountain traveller    schedule 24.04.2018
comment
Спасибо. Я думал, что Полли должна предоставлять способ легко узнать итерацию вместо использования переменной с замыканием.   -  person SaiGiridhar    schedule 24.04.2018
comment
Номер попытки предоставляется другим аспектам политики повторных попыток, таким как перехватчики политики onRetry или onRetryAsync. Предоставление дополнительных входных данных (без замыкания) коду, выполняемому с помощью политики, является общей проблемой для всех типов политик. Polly v6 намерен решить эту проблему, разрешив такие перегрузки, как .Execute<TIn, TResult>(Func<TIn, TResult> func) (со всеми обычными дополнительными вариантами Polly с CancellationToken и другими текущими входными параметрами).   -  person mountain traveller    schedule 24.04.2018


Ответы (1)


Retry Polly не предоставляет никаких встроенных функций для определения номера итерации.

int iterationNumber = 0;
policy.Execute(() => { 
   iterationNumber++;
   //  ... 
} );
person SaiGiridhar    schedule 24.04.2018