Лучшая политика повторных попыток для Refit ApiException?

Я использую и Refit, и Polly для вызова API-интерфейсов restful, и мне интересно, какой должна быть политика повтора (если есть) для Refits ApiException?

public static PolicyWrap MyRetryPolicy()
{
        // Try few times with little more time between... maybe the 
        // connection issue gets resolved
        var wireServerNetworkIssue = Policy.Handle<WebException>() 
                                    .WaitAndRetryAsync(new[] {
                                    TimeSpan.FromSeconds(1),
                                    TimeSpan.FromSeconds(2),
                                    TimeSpan.FromSeconds(4)});
        var policyList = new List<Policy>();

        // But if there is something wrong with the api
        // I should do what (if general)?
        var api = Policy.Handle<ApiException>()
                  .RetryAsync(1, onRetry: async (exception, i) =>
                  {
                       await Task.Run(() =>
                       {
                           // What would be normal to do here?
                           // Try again or do some circuit braking?
                       });
                  });

        policyList.Add(wireServerNetworkIssue);
        policyList.Add(api);

        return Policy.Wrap(policyList.ToArray());
}

И тогда я использую это так

try
{
    myApi = RestService.For<MyApi>("api base url");
    var policyWrapper = Policies.Policies.MyRetryPolicyWrapper();
    var response  = await policy.ExecuteAsync(() => myApi.SendReceiptAsync(receipt));
}
catch (ApiException apiEx)
{
  //Do something if the retry policy did´t fix it.
}
catch (WebException webEx)
{
  //Do something if the retry policy did´t fix it.
}

Вопрос

Какова будет нормальная политика повторов для ApiExceptions? Будете ли вы просто тормозить цепь или при каких обстоятельствах вы сделаете что-нибудь для восстановления?

Ответ, вероятно, "это зависит от того, что возвращает ваш сервис", но я просто должен спросить.

1 ответ

Если ApiException возвращенные содержат содержательные HttpStatusCode StatusCode свойства, вы можете выбрать, какой из этих StatusCodes заслуживает повторной попытки; Полли Ридме предлагает:

int[] httpStatusCodesWorthRetrying = {408, 500, 502, 503, 504}; 

За ApiException Специфично для вызываемого API, только знание того, что представляют собой эти специфичные для API ошибки, может указывать, следует ли их повторять.

Если вы решите отключить слишком много исключений какого-либо типа, это должно быть достигнуто путем помещения выключателя в ваш PolicyWrap, а не в пределах onRetry делегат политики повтора. Полли обсуждает "Почему отключение?" здесь, и ссылки на ряд других сообщений в блоге, посвященных выключателям, в нижней части раздела о выключателях readme.

Другие вопросы по тегам