Установить политику Polly по умолчанию с Flurl - PullRequest
0 голосов
/ 11 сентября 2018

В настоящее время я использую Polly и Flurl вместе, но у меня есть общая политика повторов, которую я должен добавлять к каждому запросу. Я заметил, что Полли позволяет вам установить значение по умолчанию, используя AddPolicyHandler (...), но для этого требуется IHttpClientBuilder, и я не вижу способа получить это от Flurl.

Я подумал, что перегрузка DefaultHttpClientFactory может быть правильным способом, но это только дает мне доступ к HttpClient, а не к IHttpClientBuilder.

Я знаю, что мог бы сделать своих собственных клиентов HttpClient и передать их во Flurl, но я бы предпочел этого избежать, если бы мог, поскольку я хотел бы, чтобы Flurl управлял их жизненным циклом.

Есть ли сейчас способ сделать то, что я хочу сделать?

1 Ответ

0 голосов
/ 11 сентября 2018

Отличный вопрос. Flurl дает вам все необходимые крючки для этого. Сначала определите DelegatingHandler, который принимает политику Полли:

public class PollyHandler : DelegatingHandler
{
    private readonly IAsyncPolicy<HttpResponseMessage> _policy;

    public PollyHandler(IAsyncPolicy<HttpResponseMessage> policy) {
        _policy = policy;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        return _policy.ExecuteAsync(ct => base.SendAsync(request, ct), cancellationToken);
    }
}

Затем создайте пользовательский IHttpClientFactory, который возвращает ваш пользовательский обработчик с обработчиком по умолчанию в качестве InnerHandler:

public class PollyFactory : DefaultHttpClientFactory
{
    private readonly IAsyncPolicy<HttpResponseMessage> _policy;

    public PollyFactory(IAsyncPolicy<HttpResponseMessage> policy) {
        _policy = policy;
    }

    public override HttpMessageHandler CreateMessageHandler() {
        return new PollyHandler(_policy) {
            InnerHandler = base.CreateMessageHandler()
        };
    }
}

Наконец, при запуске приложения определите свою политику и зарегистрируйте ее в Flurl:

var policy = Policy
    .Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
    .RetryAsync(5);

FlurlHttp.Configure(settings => settings.HttpClientFactory = new PollyFactory(policy));

Одно важное замечание: этот подход не будет работать с политикой, которая обрабатывает FlurlHttpException . Это потому, что вы перехватываете звонки на уровне HttpMessageHandler здесь. Flurl преобразует ответы и ошибки до FlurlHttpException s выше по стеку, чтобы при таком подходе они не попали в ловушку / повторную попытку. Политика в приведенном выше примере перехватывает HttpRequestException и HttpResponseMessage (с кодами состояния, отличными от 2XX), которые будут работать.

...