Задержка 14 секунд с HttpClient и Polly

Я использую httpClient для выполнения запроса POST. Я использую Полли для повторных попыток. Что происходит, так это то, что первая попытка занимает 14 секунд, хотя я указал время повтора 2 секунды. Первая попытка не удалась через 14 секунд, затем есть пауза в 2 секунды до второй попытки. Я хочу, чтобы он пробовал каждые 2 секунды и тайм-аут и повторял попытку при любой ошибке. Это правильный способ сделать это?

            var retryPolicy = Policy
                .Handle<Exception>()    // retry on any
                .WaitAndRetryAsync(6, 
                    retryAttempt => TimeSpan.FromMilliseconds(2000), 
                    (response, calculatedWaitDuration, ctx) =>
                    {
                        Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
                    });
            HttpResponseMessage httpResp = null;
            await retryPolicy.ExecuteAsync(async () =>
            {
                httpResp = await DoPost();
                httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
                return httpResp;
            });


            var respBody = await httpResp.Content.ReadAsStringAsync();
            return respBody;

            async Task<HttpResponseMessage> DoPost()
            {
                var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url)
                {
                    Content = new StringContent(json, Encoding.UTF8, Constants.JsonContentType),
                    Headers = { Authorization = await GetAuthenticationTokenAsync() }
                };
                ServicePointManager.Expect100Continue = false;
                var httpResponseMessage = await StaticHttpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
                return httpResponseMessage;
            }

person Rob Sedgwick    schedule 05.12.2018    source источник


Ответы (1)


Первая попытка занимает 14 секунд, хотя я указал время повтора 2 секунды. Первая попытка не удалась через 14 секунд, затем есть пауза в 2 секунды до второй попытки.

Это правильно. WaitAndRetry - это время ожидания после сбоя перед повторной попыткой, как указано в документации.

Я хочу, чтобы он пробовал каждые 2 секунды и тайм-аут и повторял попытку при любой ошибке.

Чтобы установить тайм-аут, используйте политику тайм-аута Polly. Чтобы установить тайм-аут и повторить попытку, объедините политики тайм-аута и Retry, используя PolicyWrap. Итак, вы можете адаптировать свой код следующим образом:

        var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(2000));

        var retryPolicy = Policy
            .Handle<Exception>()    // retry on any
            .WaitAndRetryAsync(6,  // or just RetryAsync() if you don't want any wait before retrying
                retryAttempt => /* a timespan, _if you want a wait before retrying */, 
                (response, calculatedWaitDuration, ctx) =>
                {
                    Log.LogError($"Failed attempt {attempt++}. Waited for {calculatedWaitDuration}. Exception: {response?.ToString()}");
                });

        var combinedPolicy = retryPolicy.WrapAsync(timeoutPolicy);

        HttpResponseMessage httpResp = null;
        await combinedPolicy.ExecuteAsync(async () =>
        {
            httpResp = await DoPost();
            httpResp?.EnsureSuccessStatusCode(); // throws HttpRequestException
            return httpResp;
        });

Дополнительные обсуждения и примеры см. В этом аналогичном вопросе о переполнении стека.

person mountain traveller    schedule 05.12.2018