Polly не предоставляет .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
.
person
mountain traveller
schedule
21.12.2018