ResiliencePipelineRegistry<TKey> is designed to create and cache resilience pipeline instances. The registry also implements the ResiliencePipelineProvider<TKey>, allowing read-only access to pipelines.
The registry offers these features:
- Thread-safe retrieval and dynamic creation for both generic and non-generic resilience pipelines.
- Dynamic reloading of resilience pipelines when configurations change.
- Capability to register both generic and non-generic resilience pipeline builders, enabling dynamic pipeline instance creation.
- Automated resource management, which includes disposing of resources linked to resilience pipelines.
The generic
TKey parameter sets the key type for caching individual resilience pipelines within the registry. Typically, you would use the string-based ResiliencePipelineRegistry<string>.Basic Usage
To register pipeline builders, use theTryAddBuilder(...) method. This method accepts a callback argument that configures an instance of ResiliencePipelineBuilder for the pipeline being defined. The registry supports both generic and non-generic resilience pipelines.
Please note that you do not have to call the
Build method after you have set up your pipeline on the builder parameter of the TryAddBuilder. You can call the Build if you want but it is not necessary.Dynamic Pipeline Creation
Additionally, the registry allows you to add pipelines with theGetOrAddPipeline(...) method. In this method, there’s no need to register builders. Instead, the caller provides a factory method called when the pipeline isn’t cached:
Registry Options
The constructor forResiliencePipelineRegistry<TKey> accepts a parameter of type ResiliencePipelineRegistryOptions<TKey>. This parameter lets you configure the behavior of the registry. Here’s a breakdown of the available properties:
| Property | Default Value | Description |
|---|---|---|
BuilderFactory | Function returning a new ResiliencePipelineBuilder each time. | Allows consumers to customize builder creation. |
PipelineComparer | EqualityComparer<TKey>.Default | Comparer the registry uses to fetch resilience pipelines. |
BuilderComparer | EqualityComparer<TKey>.Default | Comparer the registry uses to fetch registered pipeline builders. |
InstanceNameFormatter | null | Delegate formatting TKey to instance name. |
BuilderNameFormatter | Function returning the key.ToString() value. | Delegate formatting TKey to builder name. |
The
BuilderName and InstanceName are used in telemetry.string type are suitable, it showcases the various properties of the registry and how to set them up. This is particularly helpful when you use complex registry keys.
Dynamic Reloads
Dynamic reloading lets you refresh cached pipelines when the reload token, represented as aCancellationToken, is triggered. To enable dynamic reloads:
How Dynamic Reloads Work
Dynamic reloading is a concept anchored in the registry, while theResiliencePipelineBuilder remains agnostic to it. The registry employs callbacks to configure the builders, and these callbacks are invoked right before the creation of the pipeline. When dynamic reloading is activated, the registry monitors any changes that could affect the pipeline, seamlessly reloading it as needed. The reloading process involves invoking the callback that configures the pipeline; within this callback is also the call to the AddReloadToken method. Thus, each reload also enables dynamic reloads for that particular pipeline. As a consumer, you may opt to stop reloading by simply not invoking the AddReloadToken method. It’s crucial to note that if any error occurs during reloading, the previous pipeline is retained, reloading is halted, and Polly emits a ReloadFailed telemetry event.
Resource Disposal
The registry caches and manages all pipelines and resources linked to them. When you dispose of the registry, all pipelines created by it are also disposed of and can’t be used anymore. The following example illustrates this:Disposal Callbacks
The registry also allows for the registration of dispose callbacks. These are called when a pipeline is discarded, either because of the registry’s disposal or after the pipeline has reloaded. The example below works well with dynamic reloads, letting you dispose of theCancellationTokenSource when it’s not needed anymore.
AddReloadToken(...) and OnPipelineDisposed(...) are used to implement the EnableReloads<TOptions>(...) extension method that is used by the Dependency Injection layer.
How Resource Disposal Works
Resource disposal occurs when the registry is disposed of or when the pipeline undergoes changes due to dynamic reloads. Upon disposal, all callbacks registered through theOnPipelineDisposed method are invoked. However, actual resource disposal is deferred until the pipeline completes all outgoing executions. It’s vital to note that dispose callbacks are associated only with a specific instance of the pipeline.
Disposal of Encapsulated Rate Limiters
If you are using custom rate limiters and want to dispose them on pipeline reload or when a registry is disposed, then you should use theOnPipelineDisposed callback.
Consider the following runnable example. It creates a registry with a concurrency strategy and a chained rate limiter strategy (which contains multiple rate limiters):
OnPipelineDisposed callback.
Complex Registry Keys
Though the pipeline registry supports complex keys, we suggest you use them when defining pipelines with the Dependency Injection (DI) containers. For further information, see the section on complex pipeline keys.Key Features Summary
Thread-Safe
Thread-safe retrieval and dynamic creation of resilience pipelines.
Dynamic Reloads
Automatically reload pipelines when configuration changes.
Resource Management
Automated disposal of resources linked to resilience pipelines.
Flexible Keys
Support for both simple and complex pipeline keys.