-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle CancellationToken for Retry #2396
base: main
Are you sure you want to change the base?
Conversation
It seems like the timeout strategy also does not handle the linked CancellationToken's cancellation as The following code prints var cts = new CancellationTokenSource();
var p = new ResiliencePipelineBuilder<int>().AddTimeout(TimeSpan.FromSeconds(1)).Build();
var r = await p.ExecuteAsync(async token =>
{
await Task.Delay(500, token);
cts.Cancel();
return 1;
}, cts.Token);
Console.WriteLine(r); // 1 |
For hedging it seems like we are getting var options = new HedgingStrategyOptions<int>
{
ShouldHandle = _ => PredicateResult.True(),
MaxHedgedAttempts = 3,
Delay = TimeSpan.FromMilliseconds(100),
OnHedging = static args =>
{
Console.WriteLine("Hedging...");
return default;
}
};
var cts = new CancellationTokenSource();
var p = new ResiliencePipelineBuilder<int>().AddHedging(options).Build();
var r = await p.ExecuteAsync(async token =>
{
await Task.Delay(200);
cts.Cancel();
return 3;
}, cts.Token);
Console.WriteLine(r); Output:
|
@@ -53,6 +53,15 @@ protected internal override async ValueTask<Outcome<T>> ExecuteCore<TState>(Func | |||
{ | |||
var startTimestamp = _timeProvider.GetTimestamp(); | |||
var outcome = await StrategyHelper.ExecuteCallbackSafeAsync(callback, context, state).ConfigureAwait(context.ContinueOnCapturedContext); | |||
try | |||
{ | |||
context.CancellationToken.ThrowIfCancellationRequested(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about just checking for context.CancellationToken.IsCancellationRequested()
and then constructing the exception manually?
Alternatively, you can do the same check inside ExecuteCallbackSafeAsync
and it will apply everywhere where it is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to follow the same pattern what we already have for the _timeProvider.DelayAsync
:
Polly/src/Polly.Core/Retry/RetryResilienceStrategy.cs
Lines 106 to 113 in 4a44d0e
try | |
{ | |
await _timeProvider.DelayAsync(delay, context).ConfigureAwait(context.ContinueOnCapturedContext); | |
} | |
catch (OperationCanceledException e) | |
{ | |
return Outcome.FromException<T>(e); | |
} |
But yes for sure, I can rewrite the code to avoid try catch. Do you want?
Pull Request
The issue or feature being addressed
#2375
Details on the issue fix or feature implementation
CancellationToken
asOperationCanceledException
CancellationToken
asOperationCanceledException
CancellationToken
asOperationCanceledException
Confirm the following