Как я могу получить количество повторов в делегате, выполненном с помощью политики повторов Polly? - PullRequest
0 голосов
/ 21 декабря 2018

Я внедряю Polly, чтобы повторять запросы в моем C # веб-приложении.Мой пример кода включен в этот пост.Код работает должным образом, но последний параметр, переданный CreateFile () (в настоящее время жестко задан как 0), должен иметь значение retryAttempt.Как я могу получить значение retryAttempt в Действии Выполнения?

return Policy
    .Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
    .Or<StorageException>()
    .WaitAndRetry(maxRetryCount, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)))
    .Execute(() => CreateFile(fileContent, containerName, fileName, connectionString, 0));

1 Ответ

0 голосов
/ 21 декабря 2018

Полли не обеспечивает перегрузку .Execute(...), где счет повторных попыток является одним из входных параметров делегата, переданного в .Execute(...).Это связано с тем, что повторная попытка является лишь одной из многих политик Polly, тогда как форма перегрузок .Execute(...) должна быть общей для всех типов политик.

Для случая использования, описанного в вопросе, просто:

int count = 0;
return Policy
    .Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
    .Or<StorageException>()
    .WaitAndRetry(maxRetryCount, retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)))
    .Execute(() => CreateFile(fileContent, containerName, fileName, connectionString, count++));

В альтернативном подходе используется область действия Polly Polly.Context: экземпляр этого перемещается при каждом выполнении и доступен всем частям выполнения.

Политика повтора уже передает повторсчитать до делегата onRetry, поэтому политика может захватить это в область выполнения Context:

var retryPolicyCapturingCountIntoContext =
    Policy
        .Handle<HttpException>(x => x.StatusCode == (HttpStatusCode)429)
        .Or<StorageException>()
        .WaitAndRetry(
            maxRetryCount,
            retryAttempt => TimeSpan.FromMilliseconds(Math.Pow(retryIntervalMs, retryAttempt)),
            onRetry: (response, delay, retryCount, context) =>
            {
                context["retrycount"] = retryCount;
            });

В делегате, выполняемом через политику, мы можем выбрать число повторов из Context (заботясь о случае, когда повторных попыток еще не было):

retryPolicyCapturingCountIntoContext
    .Execute(context =>
    {
        int retryCount = (context.TryGetValue("retrycount", out var retryObject) && retryObject is int count) ? count : 0;
        CreateFile(fileContent, containerName, fileName, connectionString, retryCount);
    }, new Context());

Если вы предпочитаете избегать шума защитного кода context.TryGetValue(...), вы можете выбрать вариант инициализации context["retrycount"] перед началом выполнения:

var myContext = new Polly.Context { {"retrycount ", 0} };
retryPolicyCapturingCountIntoContext
    .Execute(
         context => CreateFile(fileContent, containerName, fileName, connectionString, (int)context["retrycount"]),
         myContext);


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

Для пользователей, которые хотят получить общее количество повторных попыток, использованных для успешного выполнения операции, в обобщенном виде - скажем, для телеметрии как части некоторой общей обработки-отправкикод инфраструктуры - см. эти примеры в блоге Стива Гордона , в котором используется подход Context.

...