Skip to content
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

Introduce RetryResilienceStrategy #1101

Merged
merged 6 commits into from
Apr 11, 2023
Merged

Conversation

martintmk
Copy link
Contributor

@martintmk martintmk commented Apr 6, 2023

The issue or feature being addressed

Contributes to #1093

Details on the issue fix or feature implementation

This PR adds the retry resilience strategy to V8. Only core functionality added for now, to be expanded later.

Some missing pieces:

  • In the follow-up we should add RetryBackoffType.ExponentialWithJitter
  • More convenience extensions to RetryResilienceStrategyBuilderExtensions (custom retries, OnRetry callbacks)

Usage:

var builder = new ResilienceStrategyBuilder();

// using the options
builder.AddRetry(new RetryStrategyOptions
{
    ShouldRetry = new ShouldRetryPredicate()
        .Exception<HttpRequestException>()
        .Result<HttpResponseMessage>(response => !response.IsSuccessStatusCode)
});

// no retry delay
builder.AddRetry(new RetryStrategyOptions
{
    ShouldRetry = new ShouldRetryPredicate()
        .Exception<HttpRequestException>()
        .Result<HttpResponseMessage>(response => !response.IsSuccessStatusCode),
   RetryDelay = TimeSpan.Zero
});


// convenience overloads
builder.AddRetry(retry => retry
    .Exception<HttpRequestException>()
    .Result<HttpResponseMessage>(response => !response.IsSuccessStatusCode)); 

// using the options (complex)
builder.AddRetry(new RetryStrategyOptions
{
    ShouldRetry = new ShouldRetryPredicate()
        .Exception<HttpRequestException>()
        .Result<HttpResponseMessage>(response => !response.IsSuccessStatusCode),
    BackoffType = RetryBackoffType.Linear,
    RetryCount = 2,
    BaseDelay = TimeSpan.FromSeconds(1),
    OnRetry = new OnRetryEvent().Add<HttpResponseMessage>(() => Console.WriteLine("On retry")),
    RetryDelayGenerator = new RetryDelayGenerator().SetGenerator<HttpResponseMessage>((outcome, args) =>
    {
        if (outcome.HasResult && outcome.Result.Headers.TryGetValues("Retry-After", out var values))
        {
            return TimeSpan.FromSeconds(int.Parse(values.First()));
        }

        return args.DelayHint;
    })
});

Confirm the following

  • I started this PR by branching from the head of the default branch
  • I have targeted the PR to merge into the default branch
  • I have included unit tests for the issue/feature
  • I have successfully run a local build

@martintmk martintmk added the v8 Issues related to the new version 8 of the Polly library. label Apr 6, 2023
@martintmk martintmk added this to the v8.0.0 milestone Apr 6, 2023
@martintmk martintmk self-assigned this Apr 6, 2023
@codecov-commenter
Copy link

codecov-commenter commented Apr 6, 2023

Codecov Report

Merging #1101 (1d008c2) into main (40606d2) will increase coverage by 0.60%.
The diff coverage is 100.00%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@            Coverage Diff             @@
##             main    #1101      +/-   ##
==========================================
+ Coverage   76.35%   76.96%   +0.60%     
==========================================
  Files         185      191       +6     
  Lines        4479     4597     +118     
  Branches      821      838      +17     
==========================================
+ Hits         3420     3538     +118     
  Misses        854      854              
  Partials      205      205              
Flag Coverage Δ
linux 76.96% <100.00%> (+0.60%) ⬆️
macos ?
windows ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/Polly.Core/Strategy/SimpleEvent.cs 100.00% <ø> (ø)
...rc/Polly.Core/Telemetry/NullResilienceTelemetry.cs 100.00% <ø> (ø)
src/Polly.Core/Retry/OnRetryArguments.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryConstants.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryDelayArguments.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryDelayGenerator.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryHelper.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryResilienceStrategy.cs 100.00% <100.00%> (ø)
.../Retry/RetryResilienceStrategyBuilderExtensions.cs 100.00% <100.00%> (ø)
src/Polly.Core/Retry/RetryStrategyOptions.cs 100.00% <100.00%> (ø)
... and 2 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

src/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs Outdated Show resolved Hide resolved
src/Polly.Core/Retry/RetryBackoffType.cs Outdated Show resolved Hide resolved
src/Polly.Core/Retry/RetryBackoffType.cs Outdated Show resolved Hide resolved
src/Polly.Core/Retry/RetryConstants.cs Outdated Show resolved Hide resolved
src/Polly.Core/Retry/RetryHelper.cs Show resolved Hide resolved
src/Polly.Core/Retry/RetryHelper.cs Outdated Show resolved Hide resolved
src/Polly.Core/Utils/TimeSpanAttribute.cs Outdated Show resolved Hide resolved
src/Polly.Core/Utils/ValidationContextExtensions.cs Outdated Show resolved Hide resolved
RetryBackoffType.Linear => (attempt + 1) * baseDelay,
RetryBackoffType.Exponential => Math.Pow(ExponentialFactor, attempt) * baseDelay,
#endif
_ => throw new ArgumentOutOfRangeException(nameof(type), type, "The retry backoff type is not supported.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, I recommend switching to use helpers for throwing exceptions in the code base. Helpers reduce code size and improve i-cache efficiency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried it here, but it doesn't work because switch expression expects the TimeSpan result type.

error CS0029: Cannot implicitly convert type 'void' to 'System.TimeSpan'

I'll leave it as it is for now.

@martintmk martintmk enabled auto-merge (squash) April 11, 2023 06:57
@martintmk martintmk merged commit 2627c45 into main Apr 11, 2023
@martintmk martintmk deleted the mtomka/RetryResilienceStrategy branch April 11, 2023 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v8 Issues related to the new version 8 of the Polly library.
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants