diff --git a/docs/migration-v8.md b/docs/migration-v8.md index 78f8e9fed71..33de7e0bce3 100644 --- a/docs/migration-v8.md +++ b/docs/migration-v8.md @@ -142,7 +142,7 @@ await pipelineT.ExecuteAsync(static async token => ``` -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -195,7 +195,7 @@ ResiliencePipeline pipeline = new ResiliencePipelineBuilder() See [fallback after retries](strategies/fallback.md#fallback-after-retries) for an example on how the strategies are executed. -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -404,7 +404,7 @@ new ResiliencePipelineBuilder().AddRetry(new RetryStrategyO ``` -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -475,7 +475,7 @@ ResiliencePipeline pipelineT = new ResiliencePipelineBuilde ``` -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -538,7 +538,7 @@ ResiliencePipeline pipelineT = new ResiliencePipelineBuilde ``` -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -588,7 +588,7 @@ ResiliencePipeline pipelineT = new ResiliencePipelineBuilde ``` -> [!IMPORTANT] +> [!TIP] > > Things to remember: > @@ -689,7 +689,7 @@ cbPolicy.Reset(); // Transitions into the Closed state ### Circuit breaker in v8 -> [!IMPORTANT] +> [!TIP] > > Polly V8 does not support the standard (*"classic"*) circuit breaker with consecutive failure counting. > @@ -756,11 +756,11 @@ await manualControl.CloseAsync(); // Transitions into the Closed state > > You could guard the `Execute{Async}` call with a condition that the circuit is not broken. This technique does **not** work with V8. > -> Under the [circuit breaker's anti-patterns](strategies/circuit-breaker.md#4---reducing-thrown-exceptions) you can find the suggested way for V8. +> Under the [circuit breaker's anti-patterns](strategies/circuit-breaker.md#reducing-thrown-exceptions) you can find the suggested way for V8. ____ -> [!IMPORTANT] +> [!TIP] > > Things to remember: > diff --git a/docs/strategies/circuit-breaker.md b/docs/strategies/circuit-breaker.md index fc003c89f1c..8353ba47b7a 100644 --- a/docs/strategies/circuit-breaker.md +++ b/docs/strategies/circuit-breaker.md @@ -308,7 +308,7 @@ sequenceDiagram Over the years, many developers have used Polly in various ways. Some of these recurring patterns may not be ideal. This section highlights the recommended practices and those to avoid. -### 1 - Using different sleep duration between retry attempts based on Circuit Breaker state +### Using different sleep duration between retry attempts based on Circuit Breaker state Imagine that we have an inner Circuit Breaker and an outer Retry strategies. @@ -318,7 +318,7 @@ We would like to define the retry in a way that the sleep duration calculation i Use a closure to branch based on circuit breaker state: - + ```cs var stateProvider = new CircuitBreakerStateProvider(); var circuitBreaker = new ResiliencePipelineBuilder() @@ -362,7 +362,7 @@ var retry = new ResiliencePipelineBuilder() Use `Context` to pass information between strategies: - + ```cs var circuitBreaker = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() @@ -406,7 +406,7 @@ var retry = new ResiliencePipelineBuilder() - The Retry strategy fetches the sleep duration dynamically without knowing any specific knowledge about the Circuit Breaker. - If adjustments are needed for the `BreakDuration`, they can be made in one place. -### 2 - Using different duration for breaks +### Using different duration for breaks In the case of Retry you can specify dynamically the sleep duration via the `DelayGenerator`. @@ -416,7 +416,7 @@ In the case of Circuit Breaker the `BreakDuration` is considered constant (can't Use `Task.Delay` inside `OnOpened`: - + ```cs static IEnumerable GetSleepDuration() { @@ -450,7 +450,7 @@ var circuitBreaker = new ResiliencePipelineBuilder() - The minimum break duration value is half a second. This implies that each sleep lasts for `sleepDurationProvider.Current` plus an additional half a second. - One might think that setting the `BreakDuration` to `sleepDurationProvider.Current` would address this, but it doesn't. This is because the `BreakDuration` is established only once and isn't re-assessed during each break. - + ```cs circuitBreaker = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() @@ -472,7 +472,7 @@ circuitBreaker = new ResiliencePipelineBuilder() The `CircuitBreakerStrategyOptions` currently do not support defining break durations dynamically. This may be re-evaluated in the future. For now, refer to the first example for a potential workaround. However, please use it with caution. -### 3 - Wrapping each endpoint with a circuit breaker +### Wrapping each endpoint with a circuit breaker Imagine that you have to call N number of services via `HttpClient`s. You want to decorate all downstream calls with the service-aware Circuit Breaker. @@ -481,7 +481,7 @@ You want to decorate all downstream calls with the service-aware Circuit Breaker Use a collection of Circuit Breakers and explicitly call `ExecuteAsync()`: - + ```cs // Defined in a common place var uriToCbMappings = new Dictionary @@ -536,7 +536,7 @@ public Downstream1Client( > It is required because the `AddPolicyHandler()` method anticipates an `IAsyncPolicy` parameter. > Please be aware that, later an `AddResilienceHandler()` will be introduced in the `Microsoft.Extensions.Http.Resilience` package which is the successor of the `Microsoft.Extensions.Http.Polly`. -### 4 - Reducing thrown exceptions +### Reducing thrown exceptions In case of Circuit Breaker when it is either in the `Open` or `Isolated` state new requests are rejected immediately. @@ -546,7 +546,7 @@ That means the strategy will throw either a `BrokenCircuitException` or an `Isol Use guard expression to call `Execute{Async}` only if the circuit is not broken: - + ```cs var stateProvider = new CircuitBreakerStateProvider(); var circuitBreaker = new ResiliencePipelineBuilder() @@ -582,7 +582,7 @@ if (stateProvider.CircuitState Use `ExecuteOutcomeAsync` to avoid throwing exception: - + ```cs var context = ResilienceContextPool.Shared.Get(); var circuitBreaker = new ResiliencePipelineBuilder() diff --git a/docs/strategies/fallback.md b/docs/strategies/fallback.md index e7f110539fb..37340084fad 100644 --- a/docs/strategies/fallback.md +++ b/docs/strategies/fallback.md @@ -111,7 +111,7 @@ sequenceDiagram When designing resilient systems, a common pattern is to use a fallback after multiple failed retry attempts. This approach is especially relevant when a fallback strategy can provide a sensible default value. - + ```cs // Define a common predicates re-used by both fallback and retries var predicateBuilder = new PredicateBuilder() @@ -156,13 +156,13 @@ Here's a breakdown of the behavior when the callback produces either an `HttpSta Over the years, many developers have used Polly in various ways. Some of these recurring patterns may not be ideal. This section highlights the recommended practices and ones to avoid. -### 1 - Using fallback to replace thrown exception +### Using fallback to replace thrown exception ❌ DON'T Throw custom exceptions from the `OnFallback` delegate: - + ```cs var fallback = new ResiliencePipelineBuilder() .AddFallback(new() @@ -183,7 +183,7 @@ Throwing an exception from a user-defined delegate can disrupt the normal contro Use `ExecuteOutcomeAsync` and then evaluate the `Exception`: - + ```cs var outcome = await WhateverPipeline.ExecuteOutcomeAsync(Action, context, "state"); if (outcome.Exception is HttpRequestException requestException) @@ -197,7 +197,7 @@ if (outcome.Exception is HttpRequestException requestException) This method lets you execute the strategy or pipeline smoothly, without unexpected interruptions. If you repeatedly find yourself writing this exception "remapping" logic, consider marking the method you wish to decorate as `private` and expose the "remapping" logic publicly. - + ```cs public static async ValueTask Action() { @@ -226,7 +226,7 @@ private static ValueTask ActionCore() ``` -### 2 - Using retry for fallback +### Using retry for fallback Suppose you have a primary and a secondary endpoint. If the primary fails, you want to call the secondary. @@ -234,7 +234,7 @@ Suppose you have a primary and a secondary endpoint. If the primary fails, you w Use retry for fallback: - + ```cs var fallback = new ResiliencePipelineBuilder() .AddRetry(new() @@ -275,7 +275,7 @@ A retry strategy by default executes the same operation up to `N` times, where ` Use fallback to call the secondary: - + ```cs var fallback = new ResiliencePipelineBuilder() .AddFallback(new() @@ -295,7 +295,7 @@ return await fallback.ExecuteAsync(CallPrimary, CancellationToken.None); - The target code is executed only once. - The fallback value is returned directly, eliminating the need for additional code like `Context` or `ExecuteOutcomeAsync()`. -### 3 - Nesting `ExecuteAsync` calls +### Nesting `ExecuteAsync` calls Combining multiple strategies can be achieved in various ways. However, deeply nesting `ExecuteAsync` calls can lead to what's commonly referred to as _`Execute` Hell_. @@ -306,7 +306,7 @@ Combining multiple strategies can be achieved in various ways. However, deeply n Nest `ExecuteAsync` calls: - + ```cs var result = await fallback.ExecuteAsync(async (CancellationToken outerCT) => { @@ -328,7 +328,7 @@ This is akin to JavaScript's [callback hell](http://callbackhell.com/) or _[the Use `ResiliencePipelineBuilder` to chain strategies: - + ```cs var pipeline = new ResiliencePipelineBuilder() .AddPipeline(timeout) diff --git a/docs/strategies/retry.md b/docs/strategies/retry.md index 22ff071dd85..f15c2363f9e 100644 --- a/docs/strategies/retry.md +++ b/docs/strategies/retry.md @@ -202,13 +202,13 @@ while (!cancellationToken.IsCancellationRequested) Over the years, many developers have used Polly in various ways. Some of these recurring patterns may not be ideal. This section highlights the recommended practices and those to avoid. -### 1 - Overusing builder methods +### Overusing builder methods ❌ DON'T Overuse `Handle/HandleResult`: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -233,7 +233,7 @@ Using multiple `Handle/HandleResult` methods is redundant. Instead of specifying Use collections and simple predicate functions: - + ```cs ImmutableArray networkExceptions = new[] { @@ -266,13 +266,13 @@ var retry = new ResiliencePipelineBuilder() Grouping exceptions simplifies the configuration and improves reusability. For example, the `networkExceptions` array can be reused in various strategies such as retry, circuit breaker, and more. -### 2 - Using retry for periodic execution +### Using retry for periodic execution ❌ DON'T Use a retry strategy to run indefinitely at a specified interval: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -297,13 +297,13 @@ Use a suitable tool to schedule recurring tasks, such as [*Quartz.Net*](https:// - Polly was not designed to support this scenario; its primary purpose is to help manage **brief** transient failures. - Specialized job scheduling tools are more memory-efficient and can be set up to withstand machine failures by using persistent storage. -### 3 - Combining multiple sleep duration strategies +### Combining multiple sleep duration strategies ❌ DON'T Mix increasing values with constant ones: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -334,7 +334,7 @@ Using this approach essentially turns the logic into a state machine. Although t Use two distinct retry strategy options and combine them: - + ```cs var slowRetries = new RetryStrategyOptions { @@ -364,7 +364,7 @@ var retry = new ResiliencePipelineBuilder() - Retry strategies can be arranged in any order (either slower first and then quicker, or the other way around). - Different triggers can be defined for the retry strategies, allowing for switches between them based on exceptions or results. The order isn't fixed, so quick and slow retries can alternate. -### 4 - Branching retry logic based on request URL +### Branching retry logic based on request URL Suppose you have an `HttpClient` and you want to add a retry only for specific endpoints. @@ -372,7 +372,7 @@ Suppose you have an `HttpClient` and you want to add a retry only for specific e Use `ResiliencePipeline.Empty` and the `?:` operator: - + ```cs var retry = IsRetryable(request.RequestUri) @@ -389,7 +389,7 @@ The triggering conditions and logic are spread across different sections. This d Use the `ShouldHandle` clause to define the triggering logic: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -405,13 +405,13 @@ var retry = new ResiliencePipelineBuilder() - The conditions for triggering are consolidated in a familiar and easily accessible location. - You don't need to specify actions for scenarios when the strategy shouldn't be triggered. -### 5 - Calling a method before/after each retry attempt +### Calling a method before/after each retry attempt ❌ DON'T Call a specific method before `Execute`/`ExecuteAsync`: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -439,7 +439,7 @@ await retry.ExecuteAsync(DoSomething); Group the two method calls: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new()) @@ -457,7 +457,7 @@ await retry.ExecuteAsync(ct => If `DoSomething` and `BeforeEachAttempt` are interdependent, group them or declare a simple wrapper to invoke them in the correct sequence. -### 6 - Having a single strategy for multiple failures +### Having a single strategy for multiple failures Suppose we have an `HttpClient` that issues a request and then we try to parse a large JSON response. @@ -465,7 +465,7 @@ Suppose we have an `HttpClient` that issues a request and then we try to parse a Use a single strategy for everything: - + ```cs var builder = new ResiliencePipelineBuilder() .AddRetry(new() @@ -494,7 +494,7 @@ Previously, it was suggested that you should combine `X` and `Y` only if they ar Define a strategy for each failure domain: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -521,7 +521,7 @@ var foo = await timeout.ExecuteAsync((ct) => JsonSerializer.DeserializeAsync + ```cs var ctsKey = new ResiliencePropertyKey("cts"); var retry = new ResiliencePipelineBuilder() @@ -560,7 +560,7 @@ Conditions for triggering retries should be located in `ShouldHandle`. Bypassing Set the condition for retry within `ShouldHandle`: - + ```cs var retry = new ResiliencePipelineBuilder() .AddRetry(new() diff --git a/docs/strategies/timeout.md b/docs/strategies/timeout.md index c512cbf62b9..4c5969ab16b 100644 --- a/docs/strategies/timeout.md +++ b/docs/strategies/timeout.md @@ -12,7 +12,7 @@ The timeout resilience strategy cancels the execution if it does not complete within the specified timeout period. If the execution is canceled by the timeout strategy, it throws a `TimeoutRejectedException`. The timeout strategy operates by wrapping the incoming cancellation token with a new one. Should the original token be canceled, the timeout strategy will transparently honor the original cancellation token without throwing a `TimeoutRejectedException`. -> ![IMPORTANT] +> [!IMPORTANT] > It is crucial that the user's callback respects the cancellation token. If it does not, the callback will continue executing even after a cancellation request, thereby ignoring the cancellation. ## Usage @@ -133,7 +133,7 @@ sequenceDiagram Ignore the cancellation token provided by the resilience pipeline: - + ```cs var pipeline = new ResiliencePipelineBuilder() .AddTimeout(TimeSpan.FromSeconds(1)) @@ -153,7 +153,7 @@ The provided callback ignores the `innerToken` passed from the pipeline and inst Respect the cancellation token provided by the pipeline: - + ```cs var pipeline = new ResiliencePipelineBuilder() .AddTimeout(TimeSpan.FromSeconds(1)) diff --git a/src/Snippets/Docs/CircuitBreaker.cs b/src/Snippets/Docs/CircuitBreaker.cs index a02b53c368f..ec454febba2 100644 --- a/src/Snippets/Docs/CircuitBreaker.cs +++ b/src/Snippets/Docs/CircuitBreaker.cs @@ -71,9 +71,9 @@ public static async Task Usage() #endregion } - public static void AntiPattern_1() + public static void AntiPattern_CircuitAwareRetry() { - #region circuit-breaker-anti-pattern-1 + #region circuit-breaker-anti-pattern-circuit-aware-retry var stateProvider = new CircuitBreakerStateProvider(); var circuitBreaker = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() @@ -107,9 +107,9 @@ public static void AntiPattern_1() } private static readonly ResiliencePropertyKey SleepDurationKey = new("sleep_duration"); - public static void Pattern_1() + public static void Pattern_CircuitAwareRetry() { - #region circuit-breaker-pattern-1 + #region circuit-breaker-pattern-circuit-aware-retry var circuitBreaker = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() { @@ -146,9 +146,9 @@ public static void Pattern_1() #endregion } - public static void AntiPattern_2() + public static void AntiPattern_SleepDurationGenerator() { - #region circuit-breaker-anti-pattern-2 + #region circuit-breaker-anti-pattern-sleep-duration-generator static IEnumerable GetSleepDuration() { for (int i = 1; i < 10; i++) @@ -176,7 +176,7 @@ static IEnumerable GetSleepDuration() #endregion - #region circuit-breaker-anti-pattern-2-ext + #region circuit-breaker-anti-pattern-sleep-duration-generator-ext circuitBreaker = new ResiliencePipelineBuilder() .AddCircuitBreaker(new() @@ -195,12 +195,12 @@ static IEnumerable GetSleepDuration() #endregion } - public static async ValueTask AntiPattern_3() + public static async ValueTask AntiPattern_CircuitPerEndpoint() { static ValueTask CallXYZOnDownstream1(CancellationToken ct) => ValueTask.CompletedTask; static ResiliencePipeline GetCircuitBreaker() => ResiliencePipeline.Empty; - #region circuit-breaker-anti-pattern-3 + #region circuit-breaker-anti-pattern-cb-per-endpoint // Defined in a common place var uriToCbMappings = new Dictionary { @@ -215,9 +215,10 @@ [new Uri("https://downstreamN.com")] = GetCircuitBreaker() #endregion } - public static async ValueTask AntiPattern_4() + private static ValueTask IssueRequest() => ValueTask.FromResult(new HttpResponseMessage()); + public static async ValueTask AntiPattern_ReduceThrownExceptions() { - #region circuit-breaker-anti-pattern-4 + #region circuit-breaker-anti-pattern-reduce-thrown-exceptions var stateProvider = new CircuitBreakerStateProvider(); var circuitBreaker = new ResiliencePipelineBuilder() @@ -244,11 +245,9 @@ is not CircuitState.Open #endregion } - private static ValueTask IssueRequest() => ValueTask.FromResult(new HttpResponseMessage()); - - public static async ValueTask Pattern_4() + public static async ValueTask Pattern_ReduceThrownExceptions() { - #region circuit-breaker-pattern-4 + #region circuit-breaker-pattern-reduce-thrown-exceptions var context = ResilienceContextPool.Shared.Get(); var circuitBreaker = new ResiliencePipelineBuilder() diff --git a/src/Snippets/Docs/Fallback.cs b/src/Snippets/Docs/Fallback.cs index 710b749c39e..cc380638a6f 100644 --- a/src/Snippets/Docs/Fallback.cs +++ b/src/Snippets/Docs/Fallback.cs @@ -81,9 +81,9 @@ public CustomNetworkException(string message, Exception innerException) } } - public static void AntiPattern_1() + public static void AntiPattern_ReplaceException() { - #region fallback-anti-pattern-1 + #region fallback-anti-pattern-replace-exception var fallback = new ResiliencePipelineBuilder() .AddFallback(new() @@ -99,10 +99,10 @@ public static void AntiPattern_1() private static readonly ResiliencePipeline WhateverPipeline = ResiliencePipeline.Empty; private static ValueTask> Action(ResilienceContext context, string state) => Outcome.FromResultAsValueTask(new HttpResponseMessage()); - public static async Task Pattern_1() + public static async Task Pattern_ReplaceException() { var context = ResilienceContextPool.Shared.Get(); - #region fallback-pattern-1 + #region fallback-pattern-replace-exception var outcome = await WhateverPipeline.ExecuteOutcomeAsync(Action, context, "state"); if (outcome.Exception is HttpRequestException requestException) @@ -114,7 +114,7 @@ public static async Task Pattern_1() ResilienceContextPool.Shared.Return(context); } - #region fallback-pattern-1-ext + #region fallback-pattern-replace-exception-ext public static async ValueTask Action() { var context = ResilienceContextPool.Shared.Get(); @@ -143,11 +143,11 @@ private static ValueTask ActionCore() private static ValueTask CallPrimary(CancellationToken ct) => ValueTask.FromResult(new HttpResponseMessage()); private static ValueTask CallSecondary(CancellationToken ct) => ValueTask.FromResult(new HttpResponseMessage()); - public static async Task AntiPattern_2() + public static async Task AntiPattern_RetryForFallback() { var fallbackKey = new ResiliencePropertyKey("fallback_result"); - #region fallback-anti-pattern-2 + #region fallback-anti-pattern-retry-for-fallback var fallback = new ResiliencePipelineBuilder() .AddRetry(new() @@ -181,9 +181,9 @@ private static ValueTask ActionCore() #endregion } - public static async ValueTask Pattern_2() + public static async ValueTask Pattern_RetryForFallback() { - #region fallback-pattern-2 + #region fallback-pattern-retry-for-fallback var fallback = new ResiliencePipelineBuilder() .AddFallback(new() @@ -200,12 +200,12 @@ private static ValueTask ActionCore() } private static ValueTask CallExternalSystem(CancellationToken ct) => ValueTask.FromResult(new HttpResponseMessage()); - public static async ValueTask AntiPattern_3() + public static async ValueTask AntiPattern_NestingExecute() { var timeout = ResiliencePipeline.Empty; var fallback = ResiliencePipeline.Empty; - #region fallback-anti-pattern-3 + #region fallback-anti-pattern-nesting-execute var result = await fallback.ExecuteAsync(async (CancellationToken outerCT) => { return await timeout.ExecuteAsync(static async (CancellationToken innerCT) => @@ -218,12 +218,12 @@ private static ValueTask ActionCore() #endregion } - public static async ValueTask Pattern_3() + public static async ValueTask Pattern_NestingExecute() { var timeout = ResiliencePipeline.Empty; var fallback = ResiliencePipeline.Empty; - #region fallback-pattern-3 + #region fallback-pattern-nesting-execute var pipeline = new ResiliencePipelineBuilder() .AddPipeline(timeout) .AddPipeline(fallback) @@ -233,9 +233,9 @@ private static ValueTask ActionCore() #endregion } - public static void FallbackAfterRetries() + public static void Pattern_FallbackAfterRetries() { - #region fallback-after-retries + #region fallback-pattern-after-retries // Define a common predicates re-used by both fallback and retries var predicateBuilder = new PredicateBuilder() diff --git a/src/Snippets/Docs/Retry.cs b/src/Snippets/Docs/Retry.cs index d1a50f03d4b..c94afb17f62 100644 --- a/src/Snippets/Docs/Retry.cs +++ b/src/Snippets/Docs/Retry.cs @@ -113,7 +113,7 @@ private static bool TryGetDelay(HttpResponseMessage response, out TimeSpan delay return false; } - public static async Task MaxDelay() + public static async Task Pattern_MaxDelay() { var cancellationToken = CancellationToken.None; @@ -150,9 +150,9 @@ await pipeline.ExecuteAsync(async token => static ValueTask SynchronizeDataAsync(CancellationToken cancellationToken) => default; } - public static void AntiPattern_1() + public static void AntiPattern_OverusingBuilder() { - #region retry-anti-pattern-1 + #region retry-anti-pattern-overusing-builder var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -170,9 +170,9 @@ public static void AntiPattern_1() #endregion } - public static void Pattern_1() + public static void Pattern_OverusingBuilder() { - #region retry-pattern-1 + #region retry-pattern-overusing-builder ImmutableArray networkExceptions = new[] { @@ -202,9 +202,9 @@ public static void Pattern_1() #endregion } - public static void AntiPattern_2() + public static void AntiPattern_PeriodicExecution() { - #region retry-anti-pattern-2 + #region retry-anti-pattern-periodic-execution var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -217,9 +217,9 @@ public static void AntiPattern_2() #endregion } - public static void AntiPattern_3() + public static void AntiPattern_SleepingStrategies() { - #region retry-anti-pattern-3 + #region retry-anti-pattern-sleeping-strategies var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -239,9 +239,9 @@ public static void AntiPattern_3() #endregion } - public static void Pattern_3() + public static void Pattern_SleepingStrategies() { - #region retry-pattern-3 + #region retry-pattern-sleeping-strategies var slowRetries = new RetryStrategyOptions { @@ -266,11 +266,11 @@ public static void Pattern_3() #endregion } - public static void AntiPattern_4() + public static void AntiPattern_BranchingByUrl() { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, ""); static bool IsRetryable(Uri? uri) => true; - #region retry-anti-pattern-4 + #region retry-anti-pattern-branching-by-url var retry = IsRetryable(request.RequestUri) @@ -280,11 +280,11 @@ public static void AntiPattern_4() #endregion } - public static void Pattern_4() + public static void Pattern_BranchingByUrl() { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, ""); static bool IsRetryable(Uri? uri) => true; - #region retry-pattern-4 + #region retry-pattern-branching-by-url var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -296,12 +296,12 @@ public static void Pattern_4() #endregion } - public static async Task AntiPattern_5() + public static async Task AntiPattern_CallingMethodBefore() { static void BeforeEachAttempt() => Debug.WriteLine("Before attempt"); static ValueTask DoSomething(CancellationToken ct) => ValueTask.CompletedTask; - #region retry-anti-pattern-5 + #region retry-anti-pattern-calling-method-before var retry = new ResiliencePipelineBuilder() .AddRetry(new() { @@ -319,12 +319,12 @@ public static async Task AntiPattern_5() #endregion } - public static async Task Pattern_5() + public static async Task Pattern_CallingMethodBefore() { static void BeforeEachAttempt() => Debug.WriteLine("Before attempt"); static ValueTask DoSomething(CancellationToken ct) => ValueTask.CompletedTask; - #region retry-pattern-5 + #region retry-pattern-calling-method-before var retry = new ResiliencePipelineBuilder() .AddRetry(new()) @@ -340,11 +340,11 @@ await retry.ExecuteAsync(ct => } private record struct Foo; - public static async Task AntiPattern_6() + public static async Task AntiPattern_MultipleFailures() { var httpClient = new HttpClient(); - #region retry-anti-pattern-6 + #region retry-anti-pattern-multiple-failures var builder = new ResiliencePipelineBuilder() .AddRetry(new() @@ -366,11 +366,11 @@ await pipeline.ExecuteAsync(static async (httpClient, ct) => #endregion } - public static async Task Pattern_6() + public static async Task Pattern_MultipleFailures() { var httpClient = new HttpClient(); - #region retry-pattern-6 + #region retry-pattern-multiple-failures var retry = new ResiliencePipelineBuilder() .AddRetry(new() @@ -394,9 +394,9 @@ await httpClient.GetStreamAsync(new Uri("endpoint"), ct), #endregion } - public static void AntiPattern_7() + public static void AntiPattern_CancellingRetry() { - #region retry-anti-pattern-7 + #region retry-anti-pattern-cancelling-retry var ctsKey = new ResiliencePropertyKey("cts"); var retry = new ResiliencePipelineBuilder() @@ -420,9 +420,9 @@ public static void AntiPattern_7() #endregion } - public static void Pattern_7() + public static void Pattern_CancellingRetry() { - #region retry-pattern-7 + #region retry-pattern-cancelling-retry var retry = new ResiliencePipelineBuilder() .AddRetry(new() diff --git a/src/Snippets/Docs/Timeout.cs b/src/Snippets/Docs/Timeout.cs index 9d05dae0a8e..6e5d375721f 100644 --- a/src/Snippets/Docs/Timeout.cs +++ b/src/Snippets/Docs/Timeout.cs @@ -67,11 +67,11 @@ public static async Task Usage() #endregion } - public static async Task IgnoreCancellationToken() + public static async Task AntiPattern_CancellationToken() { var outerToken = CancellationToken.None; - #region timeout-ignore-cancellation-token + #region timeout-anti-pattern-cancellation-token var pipeline = new ResiliencePipelineBuilder() .AddTimeout(TimeSpan.FromSeconds(1)) @@ -84,11 +84,11 @@ await pipeline.ExecuteAsync( #endregion } - public static async Task RespectCancellationToken() + public static async Task Pattern_CancellationToken() { var outerToken = CancellationToken.None; - #region timeout-respect-cancellation-token + #region timeout-pattern-cancellation-token var pipeline = new ResiliencePipelineBuilder() .AddTimeout(TimeSpan.FromSeconds(1))