Я хочу переехать из Полли в Microsoft.Extensions.Http.ResilienceAddStandardResilienceHandler. Мой сокращенный код Polly следующий:
services.AddHttpClient<MyService>()
.AddPolicyHandler((_, _) =>
{
return HttpPolicyExtensions.HandleTransientHttpError()
.Or<HttpRequestException>(exception => exception.StatusCode == HttpStatusCode.Conflict)
.WaitAndRetryAsync(3, sleepDurationProvider: i => TimeSpan.FromSeconds(i * 2));
});
Важнейшая часть здесь — HttpPolicyExtensions.HandleTransientHttpError().Or<HttpRequestException>(exception => exception.StatusCode == HttpStatusCode.Conflict), где я хочу добавить собственный случай ошибки, в котором я хочу повторить попытку.
Я действительно не знаю, как преобразовать это в новую конфигурацию.
Насколько я понимаю документацию, я могу установить пользовательскую функцию options.Retry.ShouldHandle (получает или устанавливает предикат, который определяет, следует ли выполнять повторную попытку для данного результата.)
Но тогда я не могу добавить регистр, вместо этого мне придется установить всю функцию. Реализация Microsoft по умолчанию ShouldHandle выглядит следующим образом:
public static readonly Func<TArgs, ValueTask<bool>> HandleOutcome = args => args.Outcome.Exception switch
{
OperationCanceledException => PredicateResult.False(),
Exception => PredicateResult.True(),
_ => PredicateResult.False()
};
Моя текущая конфигурация выглядит так:
services.AddHttpClient<MyService>()
.AddStandardResilienceHandler()
.Configure((options, _) =>
{
options.Retry.ShouldHandle = args =>
{
if (args.Outcome.Result?.StatusCode == HttpStatusCode.Conflict)
{
return PredicateResult.True();
}
return args.Outcome.Exception switch
{
OperationCanceledException => PredicateResult.False(),
not null => PredicateResult.True(),
_ => PredicateResult.False()
};
};
});
Эквивалентно ли это первоначальной реализации Polly?





Исходный HandleTransientHttpError можно перенести на V8 следующим образом:
public static class PollyUtils
{
public static ValueTask<bool> HandleTransientHttpError(
Outcome<HttpResponseMessage> outcome)
=> outcome switch
{
{ Exception: HttpRequestException } => PredicateResult.True(),
{ Result.StatusCode: HttpStatusCode.RequestTimeout} => PredicateResult.True(),
{ Result.StatusCode: >= HttpStatusCode.InternalServerError } => PredicateResult.True(),
_ => PredicateResult.False()
};
}
Значение по умолчанию ShouldHandle определено для срабатывания каждого исключения, кроме OperationCanceledException. Если вы отменили операцию, возможно, вам не захочется ее повторять.
Это значение по умолчанию может иметь смысл не для каждого варианта использования. Например, HttpClient во многих случаях может выдавать InvalidOperationException:
BaseAddress или Timeout после отправки запросаПовторная попытка не изменит результат операции.
Вышеупомянутую служебную функцию можно легко расширить и для запуска Conflict.
Кстати, AddStandardResilienceHandler регистрирует стратегию повтора (среди других стратегий). В результате повтора MustHandle происходит следующих событий:
HttpRequestExceptionTimeoutRejectedExceptionHttpStatusCode.InternalServerErrorCode (5XX)HttpStatusCode.RequestTimeout (408)HttpStatusCode.TooManyRequests (429)