我正试图根据响应状态码操纵polly重试策略。如果状态码是500,我需要在3分钟后重试,否则我需要在2.4秒后重试。我现在就有这样的东西,
.OrResult<RestResponse>(
(response) => {
return !response.IsSuccessful || response.StatusCode != System.Net.HttpStatusCode.Conflict;
})
.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15) })
我可以添加TimeSpan.FromSeconds(180)
,但我只想在响应状态码为500时这样做。
有办法吗?
WaitAndRetryAsync
有几个过载。在你的情况下,你已经使用了一个接受IEnumerable<TimeSpan>
的,它定义了重试计数和每次尝试之间的延迟。
有允许您动态定义sleepDurations
的重载。在这些情况下,您必须提供sleepDurationProvider
.
在下面的例子中,我使用了这个重载:
public static AsyncRetryPolicy<TResult> WaitAndRetryAsync<TResult>(
this PolicyBuilder<TResult> policyBuilder,
int retryCount,
Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider,
Func<DelegateResult<TResult>, TimeSpan, int, Context, Task> onRetryAsync)
int retryCount
:最大重试次数Func<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider
:一个用户定义的函数,它接收重试尝试的次数,尝试的结果,一个上下文,并期望返回一个TimeSpan
Func<DelegateResult<TResult>, TimeSpan, int, Context, Task> onRetryAsync
:一个用户定义的函数,如果策略应该被触发,但在睡眠之前调用
用这个你可以实现期望的行为:
.WaitAndRetryAsync(retryCount: 3,
sleepDurationProvider: (int retryCount, DelegateResult<RestResponse> response, Context ctx) =>
{
if (response.Result.StatusCode == HttpStatusCode.InternalServerError)
return TimeSpan.FromMinutes(3);
return retryCount switch
{
1 => TimeSpan.FromSeconds(2),
2 => TimeSpan.FromSeconds(5),
3 => TimeSpan.FromSeconds(15),
_ => TimeSpan.FromSeconds(1) //It won't be used due to the retryCount
};
}, onRetryAsync: (_, __, ___, ____) => Task.CompletedTask);
- 如果响应的状态码为500,则返回3分钟睡眠时间
- 对于所有其他情况,根据尝试次数决定睡眠持续时间
onRetryAsync
委托需要被定义,否则编译器不会发现这个重载