Skip to content

Commit

Permalink
Handle CancellationToken for Retry
Browse files Browse the repository at this point in the history
  • Loading branch information
peter-csala committed Nov 18, 2024
1 parent 543cd50 commit 1401b0e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 5 deletions.
11 changes: 10 additions & 1 deletion src/Polly.Core/Retry/RetryResilienceStrategy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
catch (OperationCanceledException e)
{
outcome = Outcome.FromException<T>(e);
}

var shouldRetryArgs = new RetryPredicateArguments<T>(context, outcome, attempt);
var handle = await ShouldHandle(shouldRetryArgs).ConfigureAwait(context.ContinueOnCapturedContext);
var executionTime = _timeProvider.GetElapsedTime(startTimestamp);
Expand All @@ -67,7 +76,7 @@ protected internal override async ValueTask<Outcome<T>> ExecuteCore<TState>(Func
TelemetryUtil.ReportExecutionAttempt(_telemetry, context, outcome, attempt, executionTime, handle);
}

if (context.CancellationToken.IsCancellationRequested || isLastAttempt || !handle)
if (isLastAttempt || !handle)
{
return outcome;
}
Expand Down
44 changes: 40 additions & 4 deletions test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ public void ExecuteAsync_EnsureResultNotDisposed()
}

[Fact]
public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried()
public async Task ExecuteAsync_CancellationRequestedBeforeCallback_EnsureNoAttempt()
{
SetupNoDelay();
var sut = CreateSut();
using var cancellationToken = new CancellationTokenSource();
_options.ShouldHandle = _ => PredicateResult.True();
var sut = CreateSut();

cancellationToken.Cancel();
var context = ResilienceContextPool.Shared.Get();
context.CancellationToken = cancellationToken.Token;
Expand All @@ -47,10 +49,36 @@ public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried()
}

[Fact]
public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetried()
public async Task ExecuteAsync_CancellationRequestedDuringCallback_EnsureNotRetried()
{
SetupNoDelay();
using var cancellationToken = new CancellationTokenSource();
_options.ShouldHandle = _ => PredicateResult.True();
var sut = CreateSut();

var context = ResilienceContextPool.Shared.Get();
context.CancellationToken = cancellationToken.Token;
var executed = false;
var attemptCounter = 0;

var result = await sut.ExecuteOutcomeAsync((_, _) =>
{
executed = true;
++attemptCounter;
cancellationToken.Cancel();
return Outcome.FromResultAsValueTask("dummy");
}, context, "state");

result.Exception.Should().BeOfType<OperationCanceledException>();
executed.Should().BeTrue();
attemptCounter.Should().Be(1);
}

[Fact]
public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetried()
{
SetupNoDelay();
using var cancellationToken = new CancellationTokenSource();
_options.ShouldHandle = _ => PredicateResult.True();
_options.OnRetry = _ =>
{
Expand All @@ -62,10 +90,18 @@ public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetri
var context = ResilienceContextPool.Shared.Get();
context.CancellationToken = cancellationToken.Token;
var executed = false;
var attemptCounter = 0;

var result = await sut.ExecuteOutcomeAsync((_, _) =>
{
executed = true;
++attemptCounter;
return Outcome.FromResultAsValueTask("dummy");
}, context, "state");

var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state");
result.Exception.Should().BeOfType<OperationCanceledException>();
executed.Should().BeTrue();
attemptCounter.Should().Be(1);
}

[Fact]
Expand Down

0 comments on commit 1401b0e

Please sign in to comment.