Мое первоначальное намерение состояло в том, чтобы повторить попытку несколько раз по истечении времени ожидания самого запроса, например, при попытке связаться с другой микрослужбой, которая не работает на пару секунд в надежде, что это временный сбой. Если есть более простое решение, этого будет достаточно. Я решил вручную установить тайм-аут для каждой попытки, используя политику упаковки, надеясь достичь того же результата.
Я видел подобное решение, не использующее httpclientfactory здесь Использовать определенный тайм-аут подключен к повторной политике, но у меня это не работает.
Мой код выглядит так:
services.AddHttpClient("retryclient", client =>
{
client.Timeout = TimeSpan.FromSeconds(100);
}).AddPolicyHandler((servs, request) =>
Policy.HandleResult<HttpResponseMessage>(r =>
{
return r.StatusCode == HttpStatusCode.NotFound; //(1)
}).
.OrTransiesntHttpError().
WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(retryAttempt),
onRetry: (exception, timespan, retryAttempt, context) =>
{ // using servs to log // });
}).WrapAsync(Policy.TimeoutAsync(1)));
Я проверил, что политика повторных попыток работает, когда я пытаюсь получить доступ к «ненайденному» адресу, не оборачивая политику тайм-аута, и она работает нормально. Я также пробовал использовать строку (1) с кодом состояния HttpStatusCode.RequestTimeout
вместо не найдено для моего случая, но это не работает.
Когда я использую упаковку и пытаюсь получить доступ к сервису, который не работает, он выдает Polly.Timeout.TimeoutRejectedException
с первой попытки, как я и ожидал, но больше не пытается. Я не мог придумать способ повторить попытку несколько раз, либо с установленным таймаутом для каждой попытки, либо только тогда, когда время ожидания самого запроса истекает без использования политики тайм-аута.
Изменить: после дальнейшего чтения https://cm.engineering/transient-timeouts-and-the-retry-rabbit-hole-net-4-5-f406cebbf194, похоже, моя проблема заключается в обработке политики. У меня нет доступа к токену отмены HttpClient. Я предполагаю, что могу исправить это, переопределив метод sendAsync, как показано в ссылке. Есть ли элегантный способ сделать то же самое при создании фабрики?