Как реализовать политику повторов на основе содержимого ответа HTML? - PullRequest
0 голосов
/ 15 февраля 2019

Я использую WebClient для чтения некоторого html-контента с веб-сайта, используя класс System.Net.WebClient.Иногда этот веб-сайт дает мне 200 ответов с тегом заголовка, в котором говорится, что лимит вызовов превышен, и я должен повторить попытку через несколько секунд.То, что я ищу, - это некоторая политика Retry, которая читает этот тег заголовка и проверяет, что лимит вызовов превышает ошибку.Если эта ошибка присутствует, следует повторить попытку.Вот пример кода, который делает этот вызов на сайт

        using (var wc = new GZipWebClient())
        {
            // this html sometimes contain <title> with error message
            html = await wc.DownloadStringTaskAsync(url);
        }

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

Ответы [ 2 ]

0 голосов
/ 16 февраля 2019

Политики Polly могут обрабатывать изначально , а также исключения.Нет необходимости заставлять код, выполняемый с помощью политики, генерировать исключение, чтобы вызвать повторную попытку.

var retryPolicy = Policy
    .HandleResult<string>(s => s.Contains("whatever text triggers retry")) // or whatever more complicated predicate you want
    .Retry...Async(...); // whatever flavour of retry overload you want

private async Task DownloadAsync()
{
   using (var wc = new GZipWebClient())
   {
      // this html sometimes contain <title> with error message
      html = await retryPolicy.ExecuteAsync(() => wc.DownloadStringTaskAsync(url));
   }
}

Один экземпляр политики может обрабатывать как исключения, так и результаты, поэтому обработку исключений также можно объединить вуказанная выше политика.


Если ответ от вызываемого API также содержит информацию о как долго ждать перед повторной попыткой ("RetryAfter"), то Полли также предоставляет специфичныйшаблоны, позволяющие создать политику, которая автоматически ожидает ровно столько времени, сколько указано в ответе .

0 голосов
/ 15 февраля 2019

Используйте Polly , как обычно, и генерируйте пользовательское исключение, когда вы получаете сообщение об ошибке в html.Простой пример ниже.

    private async Task DownloadAsync()
    {
       using (var wc = new GZipWebClient())
       {
          // this html sometimes contain <title> with error message
          html = await wc.DownloadStringTaskAsync(url);

          if (html.Contains("My Error Message")) 
          {
              // Log Error
              throw new MyDownloadFailedException(html);
          }
      }
   }

   // In your calling method
   var p = Policy
            .Handle<MyDownloadFailedException>()
            .RetryForever(exception =>  
            {
                // log.Warning("Failed, retrying....");
            });

   p.ExecuteAsync(async() => await DownloadAsync());
...