Как установить Polly Retry только для заданных значений c StatusCodes - PullRequest
0 голосов
/ 03 апреля 2020

У меня есть пара вопросов по поводу аналогичной проблемы: я звоню в EmailServer и использую политику Polly для WaitAndRetry. Но я бы хотел, чтобы повтор происходил только для определенных c тайм-аутов: 5xx и 429 (и игнорировать остальные 4xx).

Как сделать его более элегантным, а также охватить все возможности 5xx ( так как приведенный ниже HttpStatusCode не охватывает все 5xx, а также не охватывает 429)?

В настоящее время у меня есть следующий код (2 части / опции):

private readonly HttpStatusCode[] _retryHttpStatusCodesList =
    new[]
    {
        HttpStatusCode.InternalServerError,
        HttpStatusCode.NotImplemented,            
        HttpStatusCode.BadGateway,
        HttpStatusCode.ServiceUnavailable,
        HttpStatusCode.GatewayTimeout,
        HttpStatusCode.HttpVersionNotSupported,
        HttpStatusCode.RequestTimeout,
        HttpStatusCode.Unauthorized,
        HttpStatusCode.RequestEntityTooLarge
    };

ВАРИАНТ 1 :

   var waitAndRetryPolicy = Policy.Handle<Exception>()
                .OrResult<HttpResponseMessage>(r =>  _retryHttpStatusCodesList.Contains(r.StatusCode))
                .RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });

ВАРИАНТ 2 (этот я вообще не могу понять, как поставить проверку для StatusCode):

var waitAndRetryPolicy = Policy.Handle<Exception>()
            .WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)), 
            (ex, timeSpan) => 
            { 
                Console.WriteLine($"Log Error {ex}"); 
            });

   SendGridClient client = new SendGridClient ();
   var response = await policy.ExecuteAsync (() => 
               client.SendEmailAsync(new SendGridMessage));

1 Ответ

1 голос
/ 04 апреля 2020

Вместо словаря вы можете просто проверить код ответа напрямую:

var retryPolicy = Policy
    .Handle<Exception>()
    .OrResult<Sendgrid.Response>(r =>
    {
        var statusCode = (int)r.StatusCode;
        return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
    })
    .RetryAsync(2, (ex, retryCount) => { Console.WriteLine($"Retry count {retryCount}"); });

В ответ на ваш комментарий вам нужно всего лишь заменить вызов на RetryAsync(...) вашим кодом для WaitAndRetryAsync(...) :

var waitAndRetryPolicy = Policy
    .Handle<Exception>()
    .OrResult<Sendgrid.Response>(r =>
    {
        var statusCode = (int)r.StatusCode;
        return (statusCode >= 500 && statusCode <= 599) || statusCode == 429;
    })
    .WaitAndRetryAsync(_maxRetries, retryAttempt => TimeSpan.FromMinutes(Math.Pow(_waitMinutes, retryAttempt)),
        (ex, timeSpan) =>
        {
            Console.WriteLine($"Log Error {ex}");
        });

Помните, что Polly - свободный политик. Это означает, что методы в экземпляре PolicyBuilder<T>, который вы вызываете (например, .Handle<Exception>() и .OrResult<Sendgrid.Response>()), конфигурируют этого компоновщика для создания Policy<T> с вызовом, таким как .WaitAndRetryAsync() или RetryAsync(). Методы настройки не имеют значения, какой тип политики вы хотите создать, поэтому их можно использовать для любого типа политики.

...