-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
26 changed files
with
1,839 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Dependency Injection | ||
|
||
🚧 This documentation is being written as part of the Polly v8 release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Extensibility | ||
|
||
🚧 This documentation is being written as part of the Polly v8 release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
# General | ||
|
||
> [!NOTE] | ||
> This is documentation for the upcoming Polly v8 release. | ||
## Supported targets | ||
|
||
Polly targets .NET Standard 2.0+ ([coverage](https://docs.microsoft.com/dotnet/standard/net-standard#net-implementation-support): .NET Core 2.0+, .NET Core 3.0, .NET 6.0+ and later Mono, Xamarin and UWP targets). The NuGet package also includes direct targets for .NET Framework 4.6.1 and 4.7.2. | ||
|
||
For details of supported compilation targets by version, see the [supported targets](https://github.com/App-vNext/Polly/wiki/Supported-targets) grid. | ||
|
||
## Asynchronous support | ||
|
||
Polly provides native support for asynchronous operations through all its resilience strategies by offering the `ExecuteAsync` methods on the `ResiliencePipeline` class. | ||
|
||
### SynchronizationContext | ||
|
||
By default, asynchronous continuations and retries do not execute on a captured synchronization context. To modify this behavior, you can use the `ResilienceContext` class and set its `ContinueOnCapturedContext` property to `true`. The following example illustrates this: | ||
|
||
<!-- snippet: synchronization-context --> | ||
```cs | ||
// Retrieve an instance of ResilienceContext from the pool | ||
// with the ContinueOnCapturedContext property set to true | ||
ResilienceContext context = ResilienceContextPool.Shared.Get(continueOnCapturedContext: true); | ||
|
||
await pipeline.ExecuteAsync( | ||
async context => | ||
{ | ||
// Execute your code, honoring the ContinueOnCapturedContext setting | ||
await MyMethodAsync(context.CancellationToken).ConfigureAwait(context.ContinueOnCapturedContext); | ||
}, | ||
context); | ||
|
||
// Optionally, return the ResilienceContext instance back to the pool | ||
// to minimize allocations and enhance performance | ||
ResilienceContextPool.Shared.Return(context); | ||
``` | ||
<!-- endSnippet --> | ||
|
||
### Cancellation support | ||
|
||
Asynchronous pipeline execution in Polly supports cancellation. This is facilitated through the `ExecuteAsync(...)` method overloads that accept a `CancellationToken`, or by initializing the `ResilienceContext` class with the `CancellationToken` property. | ||
|
||
The `CancellationToken` you pass to the `ExecuteAsync(...)` method serves multiple functions: | ||
|
||
- It cancels resilience actions such as retries, wait times between retries, or rate-limiter leases. | ||
- It is passed to any delegate executed by the strategy as a `CancellationToken` parameter, enabling cancellation during the delegate's execution. | ||
- Is consistent with the .NET Base Class Library's (BCL) behavior in `Task.Run(...)`, if the cancellation token is cancelled before execution begins, the user-defined delegate will not execute at all. | ||
|
||
<!-- snippet: cancellation-token --> | ||
```cs | ||
// Execute your code with cancellation support | ||
await pipeline.ExecuteAsync( | ||
async token => await MyMethodAsync(token), | ||
cancellationToken); | ||
|
||
// Use ResilienceContext for more advanced scenarios | ||
ResilienceContext context = ResilienceContextPool.Shared.Get(cancellationToken: cancellationToken); | ||
|
||
await pipeline.ExecuteAsync( | ||
async context => await MyMethodAsync(context.CancellationToken), | ||
context); | ||
``` | ||
<!-- endSnippet --> | ||
|
||
## Thread safety | ||
|
||
All Polly resilience strategies are fully thread-safe. You can safely re-use strategies at multiple call sites, and execute through strategies concurrently on different threads. | ||
|
||
> [!IMPORTANT] | ||
> While the internal operation of the strategy is thread-safe, this does not automatically make delegates you execute through the strategy thread-safe: if delegates you execute through the strategy are not thread-safe, they remain not thread-safe. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
# Resilience Context | ||
|
||
> [!NOTE] | ||
> This is documentation for the upcoming Polly v8 release. | ||
The `ResilienceContext` class in Polly provides an execution-scoped instance that accompanies each execution through a Polly resilience strategy. This class serves to share context and facilitate information exchange between the pre-execution, mid-execution, and post-execution phases. | ||
|
||
The resilience context exposes several properties: | ||
|
||
- `OperationKey`: A user-defined identifier for the operation. | ||
- `CancellationToken`: The cancellation token linked to the operation. | ||
- `Properties`: An instance of `ResilienceProperties` for attaching custom data to the context. | ||
- `ContinueOnCapturedContext`: Specifies whether the asynchronous execution should continue on the captured context. | ||
|
||
## Usage | ||
|
||
Below is an example demonstrating how to work with `ResilienceContext`: | ||
|
||
<!-- snippet: resilience-context --> | ||
```cs | ||
// Retrieve a context with a cancellation token | ||
ResilienceContext context = ResilienceContextPool.Shared.Get(cancellationToken); | ||
|
||
// Attach custom data to the context | ||
context.Properties.Set(MyResilienceKeys.Key1, "my-data"); | ||
context.Properties.Set(MyResilienceKeys.Key2, 123); | ||
|
||
// Utilize the context in a resilience pipeline | ||
ResiliencePipeline pipeline = new ResiliencePipelineBuilder() | ||
.AddRetry(new() | ||
{ | ||
OnRetry = static args => | ||
{ | ||
// Retrieve custom data from the context, if available | ||
if (args.Context.Properties.TryGetValue(MyResilienceKeys.Key1, out var data)) | ||
{ | ||
Console.WriteLine("OnRetry, Custom Data: {0}", data); | ||
} | ||
|
||
return default; | ||
} | ||
}) | ||
.Build(); | ||
|
||
// Execute the resilience pipeline asynchronously | ||
await pipeline.ExecuteAsync( | ||
async context => | ||
{ | ||
// Insert your execution logic here | ||
}, | ||
context); | ||
|
||
// Return the context to the pool | ||
ResilienceContextPool.Shared.Return(context); | ||
``` | ||
<!-- endSnippet --> | ||
|
||
Where `ResilienceKeys` is defined as: | ||
|
||
<!-- snippet: resilience-keys --> | ||
```cs | ||
public static class MyResilienceKeys | ||
{ | ||
public static readonly ResiliencePropertyKey<string> Key1 = new("my-key-1"); | ||
|
||
public static readonly ResiliencePropertyKey<int> Key2 = new("my-key-2"); | ||
} | ||
``` | ||
<!-- endSnippet --> | ||
|
||
## Resilient context pooling | ||
|
||
<!-- Overview --> | ||
The `ResilienceContext` object is resource-intensive to create, and recreating it for each execution would negatively impact performance. To address this issue, Polly provides a `ResilienceContextPool`. This pool allows you to obtain and reuse `ResilienceContext` instances. Once you've finished using a context instance, you can return it to the pool. This action will reset the context to its initial state, making it available for reuse. | ||
|
||
<!-- Methods --> | ||
The `ResilienceContextPool` offers several `Get` methods. These methods not only allow you to retrieve a `ResilienceContext` instance, but also enable you to initialize some of its properties at the time of retrieval. | ||
|
||
<!-- snippet: resilience-context-pool --> | ||
```cs | ||
// Retrieve a context with a cancellation token | ||
ResilienceContext context = ResilienceContextPool.Shared.Get(cancellationToken); | ||
|
||
try | ||
{ | ||
// Retrieve a context with a specific operation key | ||
context = ResilienceContextPool.Shared.Get("my-operation-key", cancellationToken); | ||
|
||
// Retrieve a context with multiple properties | ||
context = ResilienceContextPool.Shared.Get( | ||
operationKey: "my-operation-key", | ||
continueOnCapturedContext: true, | ||
cancellationToken: cancellationToken); | ||
|
||
// Use the pool here | ||
} | ||
finally | ||
{ | ||
// Returning the context back to the pool is recommended, but not required as it reduces the allocations. | ||
// It is also OK to not return the context in case of exceptions, if you want to avoid try-catch blocks. | ||
ResilienceContextPool.Shared.Return(context); | ||
} | ||
``` | ||
<!-- endSnippet --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Resilience Pipeline Registry | ||
|
||
> [!NOTE] | ||
> This is documentation for the upcoming Polly v8 release. | ||
The `ResiliencePipelineRegistry<TKey>` is a generic class that provides the following functionalities: | ||
|
||
- Thread-safe retrieval and dynamic creation of both generic and non-generic resilience pipelines. | ||
- Dynamic reloading of resilience pipelines when configurations change. | ||
- Support for registering both generic and non-generic resilience pipeline builders, enabling dynamic pipeline instance creation. | ||
- Automatic resource management, including disposal of resources tied to resilience pipelines. | ||
|
||
> [!NOTE] | ||
> The generic `TKey` parameter specifies the key type used for caching individual resilience pipelines within the registry. In most use-cases, you will be working with `ResiliencePipelineRegistry<string>`. | ||
## Usage | ||
|
||
🚧 This documentation is being written as part of the Polly v8 release. |
Oops, something went wrong.