From d6af96d963bbc667c1ff5f824ab78917408fde9c Mon Sep 17 00:00:00 2001 From: Chris R Date: Thu, 2 Nov 2023 15:53:05 -0700 Subject: [PATCH 1/6] Http resilience readme --- ...icrosoft.Extensions.Http.Resilience.csproj | 2 +- .../README.md | 36 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Microsoft.Extensions.Http.Resilience.csproj b/src/Libraries/Microsoft.Extensions.Http.Resilience/Microsoft.Extensions.Http.Resilience.csproj index cbcd8e307e1..26ad109d592 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/Microsoft.Extensions.Http.Resilience.csproj +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Microsoft.Extensions.Http.Resilience.csproj @@ -1,7 +1,7 @@  Microsoft.Extensions.Http.Resilience - Resilience mechanisms for HTTP Client. + Resilience mechanisms for HttpClient. Resilience diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md index a8bc4f54144..d6bca5161b2 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md @@ -1,6 +1,6 @@ # Microsoft.Extensions.Http.Resilience -Resilience mechanisms for HTTP Client. +Resilience mechanisms for `HttpClient` built on the [Polly framework](https://www.pollydocs.org/). ## Install the package @@ -18,6 +18,40 @@ Or directly in the C# project file: ``` +## Usage Examples + +When configuring an HttpClient through the client factory the following extensions can add a set of pre-configured hedging or resilience behaviors. These pipelines combine multiple strategies with pre-configured defaults. +- The total request timeout pipeline applies an overall timeout to the execution, ensuring that the request including hedging attempts, does not exceed the configured limit. +- The retry pipeline retries the request in case the dependency is slow or returns a transient error. +- The bulkhead pipeline limits the maximum number of concurrent requests being send to the dependency. +- The circuit breaker blocks the execution if too many direct failures or timeouts are detected. +- The attempt timeout pipeline limits each request attempt duration and throws if its exceeded. + +### Resilience + +The standard resilience pipeline makes use of the above strategies to ensure HTTP requests can be sent reliably. + +```csharp +var clientBuilder = services.AddHttpClient("MyClient"); + +clientBuilder.AddStandardResilienceHandler().Configure(o => +{ + o.CircuitBreaker.MinimumThroughput = 10; +}); +``` + +### Hedging + +The standard hedging pipeline uses a pool of circuit breakers to ensure that unhealthy endpoints are not hedged against. By default, the selection from pool is based on the URL Authority (scheme + host + port). It is recommended that you configure the way the strategies are selected by calling the `SelectPipelineByAuthority()` extensions. The last three strategies are applied to each individual endpoint. + +```csharp +var clientBuilder = services.AddHttpClient("MyClient"); + +clientBuilder.AddStandardHedgingHandler().Configure(o => +{ + o.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(10); +}); +``` ## Feedback & Contributing From cb47182b74d28c4549993b05887106548cbadc90 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 3 Nov 2023 10:31:56 -0700 Subject: [PATCH 2/6] Update HttpStandardHedgingResilienceOptions.cs --- .../Hedging/HttpStandardHedgingResilienceOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/HttpStandardHedgingResilienceOptions.cs b/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/HttpStandardHedgingResilienceOptions.cs index e0c9c2f1afb..74a00aafc82 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/HttpStandardHedgingResilienceOptions.cs +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/Hedging/HttpStandardHedgingResilienceOptions.cs @@ -22,7 +22,7 @@ namespace Microsoft.Extensions.Http.Resilience; /// Total request timeout strategy applies an overall timeout to the execution, /// ensuring that the request including hedging attempts does not exceed the configured limit. /// The hedging strategy executes the requests against multiple endpoints in case the dependency is slow or returns a transient error. -/// The bulkhead policy limits the maximum number of concurrent requests being send to the dependency. +/// The rate limiter pipeline limits the maximum number of requests being send to the dependency. /// The circuit breaker blocks the execution if too many direct failures or timeouts are detected. /// The attempt timeout strategy limits each request attempt duration and throws if its exceeded. /// From fc7fb0ab7ea5c5f711db2ba180418fa6adc7fecf Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Fri, 3 Nov 2023 10:33:20 -0700 Subject: [PATCH 3/6] Apply suggestions from code review Co-authored-by: martintmk <103487740+martintmk@users.noreply.github.com> --- src/Libraries/Microsoft.Extensions.Http.Resilience/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md index d6bca5161b2..7072cb5eefd 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md @@ -20,10 +20,10 @@ Or directly in the C# project file: ## Usage Examples -When configuring an HttpClient through the client factory the following extensions can add a set of pre-configured hedging or resilience behaviors. These pipelines combine multiple strategies with pre-configured defaults. +When configuring an HttpClient through the [HTTP client factory](https://learn.microsoft.com/dotnet/core/extensions/httpclient-factory) the following extensions can add a set of pre-configured hedging or resilience behaviors. These pipelines combine multiple resilience strategies with pre-configured defaults. - The total request timeout pipeline applies an overall timeout to the execution, ensuring that the request including hedging attempts, does not exceed the configured limit. - The retry pipeline retries the request in case the dependency is slow or returns a transient error. -- The bulkhead pipeline limits the maximum number of concurrent requests being send to the dependency. +- The rate limiter pipeline limits the maximum number of requests being send to the dependency. - The circuit breaker blocks the execution if too many direct failures or timeouts are detected. - The attempt timeout pipeline limits each request attempt duration and throws if its exceeded. From d7b8a86bfbab7a5742ec5c19dd03941386f77200 Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 3 Nov 2023 11:23:39 -0700 Subject: [PATCH 4/6] Custom pipeline --- .../README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md index 7072cb5eefd..65a5b269dac 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md @@ -53,6 +53,21 @@ clientBuilder.AddStandardHedgingHandler().Configure(o => }); ``` +### Custom Resilience + +For more granular control a custom pipeline can be constructed. + +```csharp +var clientBuilder = services.AddHttpClient("MyClient"); + +clientBuilder.AddResilienceHandler("myHandler") + .AddBulkheadPolicy("customBulkhead", b => { }) + .AddTimeoutPolicy("customTimeout", t => { }) + .AddRetryPolicy("customRetry", r => { }) + .AddFallbackPolicy("customFallback", f => { }) + .AddCircuitBreakerPolicy("customCircuit", c => { }); +``` + ## Feedback & Contributing We welcome feedback and contributions in [our GitHub repo](https://github.com/dotnet/extensions). From d893a1b6d0374ac13d229e3e15618451e976a98a Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 3 Nov 2023 11:48:08 -0700 Subject: [PATCH 5/6] Fixup --- .../Microsoft.Extensions.Http.Resilience/README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md index 65a5b269dac..72371d88055 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md @@ -60,12 +60,14 @@ For more granular control a custom pipeline can be constructed. ```csharp var clientBuilder = services.AddHttpClient("MyClient"); -clientBuilder.AddResilienceHandler("myHandler") - .AddBulkheadPolicy("customBulkhead", b => { }) - .AddTimeoutPolicy("customTimeout", t => { }) - .AddRetryPolicy("customRetry", r => { }) - .AddFallbackPolicy("customFallback", f => { }) - .AddCircuitBreakerPolicy("customCircuit", c => { }); +clientBuilder.AddResilienceHandler("myHandler", b => +{ + b.AddConcurrencyLimiter(new ConcurrencyLimiterOptions()) + .AddTimeout(new TimeoutStrategyOptions()) + .AddRetry(new RetryStrategyOptions()) + .AddFallback(new FallbackStrategyOptions()) + .AddCircuitBreaker(new CircuitBreakerStrategyOptions()); +}); ``` ## Feedback & Contributing From 8a6cbc2f96e6fa70ce8e331b398e6a04a7de07d2 Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 3 Nov 2023 16:04:12 -0700 Subject: [PATCH 6/6] Better pipeline --- .../Microsoft.Extensions.Http.Resilience/README.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md index 72371d88055..676ffc34118 100644 --- a/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md +++ b/src/Libraries/Microsoft.Extensions.Http.Resilience/README.md @@ -62,11 +62,14 @@ var clientBuilder = services.AddHttpClient("MyClient"); clientBuilder.AddResilienceHandler("myHandler", b => { - b.AddConcurrencyLimiter(new ConcurrencyLimiterOptions()) - .AddTimeout(new TimeoutStrategyOptions()) - .AddRetry(new RetryStrategyOptions()) - .AddFallback(new FallbackStrategyOptions()) - .AddCircuitBreaker(new CircuitBreakerStrategyOptions()); + b.AddFallback(new FallbackStrategyOptions() + { + FallbackAction = _ => Outcome.FromResultAsValueTask(new HttpResponseMessage(HttpStatusCode.ServiceUnavailable)) + }) + .AddConcurrencyLimiter(100) + .AddRetry(new HttpRetryStrategyOptions()) + .AddCircuitBreaker(new HttpCircuitBreakerStrategyOptions()) + .AddTimeout(new HttpTimeoutStrategyOptions()); }); ```