Replies: 4 comments 12 replies
-
@lonix1 Hi, do you already have this knowledge? I need this solution also. |
Beta Was this translation helpful? Give feedback.
-
I think there is some misunderstanding so, let me try to clarify. Registry and PipelineSo, whenever you register a pipeline inside a registry then you can't dispose the pipeline directly. (The Polly/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs Lines 439 to 446 in 4f0d44a You can only dispose the pipeline through the registry: Polly/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs Lines 410 to 436 in 4f0d44a Disposed PipelineAfter the registry has been disposed you obviously can't retrieve a pipeline because you will get an Let's suppose you have retrieved a pipeline just before the registry disposal. If you want to invoke a method on the pipeline like the Retrieving a strategy from a pipeline can be achieved via var registry = new ResiliencePipelineRegistry<string>();
registry.TryAddBuilder("A", (builder, _) =>
{
builder.AddRateLimiter(new SlidingWindowRateLimiter(
new SlidingWindowRateLimiterOptions
{
PermitLimit = 10,
Window = TimeSpan.FromMinutes(1),
SegmentsPerWindow = 1
}));
});
var pipeline = registry.GetPipeline("A");
registry.Dispose();
try
{
pipeline.Execute(() => {});
}
catch(ObjectDisposedException)
{
Console.WriteLine("Pipeline has been disposed");
}
var strategy = pipeline.GetPipelineDescriptor().FirstStrategy.StrategyInstance;
var executeCore = typeof(ResilienceStrategy).GetMethod("ExecuteCore", BindingFlags.Instance | BindingFlags.NonPublic);
executeCore = executeCore.MakeGenericMethod(new[] {typeof(object), typeof(object)});
var context = ResilienceContextPool.Shared.Get();
Func<ResilienceContext, object, ValueTask<Outcome<object>>> callback = (_, __) => Outcome.FromResultAsValueTask<object>("Test");
var executeTask = (ValueTask<Outcome<object>>)executeCore.Invoke(strategy, parameters: [callback, context, null]);
var executeOutcome = await executeTask;
ResilienceContextPool.Shared.Return(context);
Console.WriteLine(executeOutcome.Result); It will print
So, as you can see the pipeline is disposed but the strategy isn't. |
Beta Was this translation helpful? Give feedback.
-
Happy New Year @peter-csala. Thanks for that detail, it's helpful. To be sure I understand you, here is a simplified example: _resiliencePipelineRegistry.TryAddBuilder("A", (builder, context) => {
builder.AddRateLimiter(new RateLimiterStrategyOptions {
RateLimiter = args => CreateRateLimiter(...).AcquireAsync(...) // (1)
});
builder.AddRateLimiter(new RateLimiterStrategyOptions {
RateLimiter = args => PartitionedRateLimiter.CreateChained(...).AcquireAsync(...) // (2)
});
}); I'm using IDisposableAnalyzers to detect undisposed resources. It warns me that both Will those rate limiters (even a "chained" one which contains other limiters) be disposed by the registry itself? |
Beta Was this translation helpful? Give feedback.
-
Happy New Year @lonix1 you too! Polly.CoreLet's see what happens when you call the
As you can see on the following image the So, if the given strategy is disposable then it will be disposed. BUT not all strategies are disposable. For example the Polly.RateLimitingThe things are bit tricky here.
BUT inside the If the So, your limiter won't be disposed because the underlying strategies |
Beta Was this translation helpful? Give feedback.
-
One benefit of the "resilience registry" is that it is easy to dispose:
Does that also include chained rate limiters?
Suppose I have a pipeline with multiple limiters (e.g. concurrency limiter and rate limiter) and also a chained rate limiter which itself contains rate limiters - are all of those disposed when the registry is disposed?
Beta Was this translation helpful? Give feedback.
All reactions