Reputation: 175
I am trying to manipulate polly retry policy based on response status code. If status code is 500, I need to retry after 3 minutes else I need to retry after 2, 4 seconds. I have something like this right now,
.OrResult<RestResponse>(
(response) => {
return !response.IsSuccessful || response.StatusCode != System.Net.HttpStatusCode.Conflict;
})
.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15) })
I can possibly add TimeSpan.FromSeconds(180)
but I only want to do it if the response status code is 500.
Is there a way to do that?
Upvotes: 1
Views: 4347
Reputation: 22849
The WaitAndRetryAsync
has several overloads. In your case you have used one which accepts an IEnumerable<TimeSpan>
which defines the retry count and the delays between each attempt.
There are overloads which allows you to define the sleepDurations
dynamically. In those cases you have to provide a sleepDurationProvider
.
In the bellow example I've used this overload:
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
: At most how many retry attempts should be issuedFunc<int, DelegateResult<TResult>, Context, TimeSpan> sleepDurationProvider
: A user-defined function which receives the number of retry attempt, the result of the attempt, a context and anticipates a TimeSpan
in returnFunc<DelegateResult<TResult>, TimeSpan, int, Context, Task> onRetryAsync
: A user-defined function which is called if the policy should be triggered but before the sleepWith this you can achieve the desired behaviour:
.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);
onRetryAsync
delegate needs to be defined otherwise the compiler will not find this overloadUpvotes: 1