extensions icon indicating copy to clipboard operation
extensions copied to clipboard

Missing documentation about standard HTTP resilience values

Open joegoldman2 opened this issue 1 year ago • 4 comments

The current documentation is not saying anything about the default values for the total request timeout, attempt timeout, number of retries, circuit breaker break duration, failure ratio, etc when using httpClientBuilder.AddStandardResilienceHandler();

joegoldman2 avatar Apr 03 '24 11:04 joegoldman2

I was also looking for HttpStandardResilienceOptions defaults so logged it as JSON in AddStandardResilienceHandler and found the following. Note have filtered out "ShouldHandle", "DelayGenerator", "Randomizer" from this as they are too large to attach here.

{
  "RateLimiter": {
    "RateLimiter": null,
    "DefaultRateLimiterOptions": {
      "PermitLimit": 1000,
      "QueueProcessingOrder": "OldestFirst",
      "QueueLimit": 0
    },
    "OnRejected": null,
    "Name": "Standard-RateLimiter"
  },
  "TotalRequestTimeout": {
    "Timeout": "00:00:30",
    "TimeoutGenerator": null,
    "OnTimeout": null,
    "Name": "Standard-TotalRequestTimeout"
  },
  "Retry": {
    "ShouldRetryAfterHeader": true,
    "MaxRetryAttempts": 3,
    "BackoffType": "Exponential",
    "UseJitter": true,
    "Delay": "00:00:02",
    "MaxDelay": null,
    "OnRetry": null,
    "Name": "Standard-Retry"
  },
  "CircuitBreaker": {
    "FailureRatio": 0.1,
    "MinimumThroughput": 100,
    "SamplingDuration": "00:00:30",
    "BreakDuration": "00:00:05",
    "BreakDurationGenerator": null,
    "OnClosed": null,
    "OnOpened": null,
    "OnHalfOpened": null,
    "ManualControl": null,
    "StateProvider": null,
    "Name": "Standard-CircuitBreaker"
  },
  "AttemptTimeout": {
    "Timeout": "00:00:10",
    "TimeoutGenerator": null,
    "OnTimeout": null,
    "Name": "Standard-AttemptTimeout"
  }
}
dotnet --version
8.0.203

ghost avatar Apr 10 '24 09:04 ghost

+1 I tried to follow the readme file and convert the existing code which uses Microsoft.Extensions.Http.Polly

.AddPolicyHandler(
    static _ => HttpPolicyExtensions.HandleTransientHttpError()
        .OrResult(static r => r.StatusCode == System.Net.HttpStatusCode.NotFound)
        .WaitAndRetryAsync(
            10,
            static (_, result, _) => result.Result?.Headers.RetryAfter?.Delta.GetValueOrDefault() ?? TimeSpan.FromSeconds(5),
            static (_, _, _, _) => Task.CompletedTask));

to use new Microsoft.Extensions.Http.Resilience, but the documentation is lacking. Please create a migration guide.

abatishchev avatar May 19 '24 17:05 abatishchev

Related to this, I would love to see an explanation for why the policies are there in the order they are in.

As an example, why is the total request timeout policy inside/after the rate limit policy, when the rate limit policy can cause large delays if you enable queueing? For example...if you have a queue size of 10 and parallelism 1 and total request timeout = 30s, in the worst case scenario it could take that 10th queued request up to 300s, which is 10x higher than the total request timeout.

This is either bad or I'm misunderstanding something, and it would be much easier to tell which if the motivation behind the standard policies were shared.

tyler-boyd avatar May 27 '24 13:05 tyler-boyd

As an example, why is the total request timeout policy inside/after the rate limit policy, when the rate limit policy can cause large delays if you enable queueing?

This is a very good point and you are correct. Total timeout should cancel executions queued by rate limiter.

We should change the order of strategies, total timeout should be on top. This is behavioral change, however, it's varanted.

@tyler-boyd Can you create an improvement or bug fix ticket please?

Cc @iliar-turdushev, @geeknoid

martintmk avatar May 28 '24 04:05 martintmk

@abatishchev digging through the Polly.Extension code I figured out the following equivalent:

HttpPolicyExtensions.HandleTransientHttpError()

Policy<HttpResponseMessage>
                .Handle<HttpRequestException>()
                .OrResult(
                    (HttpResponseMessage response) =>
                    {
                        return (int)response.StatusCode >= 500
                            || response.StatusCode == HttpStatusCode.RequestTimeout;
                    }
                )

https://github.com/App-vNext/Polly.Extensions.Http/blob/93b91c4359f436bda37f870c4453f25555b9bfd8/src/Polly.Extensions.Http/HttpPolicyExtensions.cs#L28

aherrick avatar Jul 12 '24 12:07 aherrick

Closing as the default values have been added to the documentation.

joegoldman2 avatar Sep 15 '24 15:09 joegoldman2