Skip to content

Commit 32a3390

Browse files
authored
Cleanup ResiliencePipelineRegistry internals (#1510)
1 parent 282297e commit 32a3390

File tree

3 files changed

+88
-41
lines changed

3 files changed

+88
-41
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using Polly.Telemetry;
2+
using Polly.Utils.Pipeline;
3+
4+
namespace Polly.Registry;
5+
6+
/// <summary>
7+
/// Builds a <see cref="PipelineComponent"/> used by the registry.
8+
/// </summary>
9+
internal class RegistryPipelineComponentBuilder<TBuilder, TKey>
10+
where TBuilder : ResiliencePipelineBuilderBase
11+
where TKey : notnull
12+
{
13+
private readonly Func<TBuilder> _activator;
14+
private readonly TKey _key;
15+
private readonly string _builderName;
16+
private readonly string? _instanceName;
17+
private readonly Action<TBuilder, ConfigureBuilderContext<TKey>> _configure;
18+
19+
public RegistryPipelineComponentBuilder(
20+
Func<TBuilder> activator,
21+
TKey key,
22+
string builderName,
23+
string? instanceName,
24+
Action<TBuilder, ConfigureBuilderContext<TKey>> configure)
25+
{
26+
_activator = activator;
27+
_key = key;
28+
_builderName = builderName;
29+
_instanceName = instanceName;
30+
_configure = configure;
31+
}
32+
33+
internal PipelineComponent CreateComponent()
34+
{
35+
var builder = CreateBuilder();
36+
var telemetry = new ResilienceStrategyTelemetry(
37+
new ResilienceTelemetrySource(_builderName, _instanceName, null),
38+
builder.Listener);
39+
40+
var initialPipeline = builder.ComponentFactory();
41+
42+
if (builder.ReloadTokenProducer is null)
43+
{
44+
return initialPipeline;
45+
}
46+
47+
return PipelineComponentFactory.CreateReloadable(
48+
initialPipeline,
49+
builder.ReloadTokenProducer(),
50+
() => CreateBuilder().ComponentFactory(),
51+
telemetry);
52+
}
53+
54+
private Builder CreateBuilder()
55+
{
56+
var context = new ConfigureBuilderContext<TKey>(_key, _builderName, _instanceName);
57+
var builder = _activator();
58+
builder.Name = _builderName;
59+
builder.InstanceName = _instanceName;
60+
_configure(builder, context);
61+
62+
return new(
63+
builder.BuildPipelineComponent,
64+
context.ReloadTokenProducer,
65+
builder.TelemetryListener);
66+
}
67+
68+
private record Builder(
69+
Func<PipelineComponent> ComponentFactory,
70+
Func<Func<CancellationToken>>? ReloadTokenProducer,
71+
TelemetryListener? Listener);
72+
}

src/Polly.Core/Registry/ResiliencePipelineRegistry.TResult.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ public ResiliencePipeline<TResult> GetOrAdd(TKey key, Action<ResiliencePipelineB
4949
{
5050
var context = new ConfigureBuilderContext<TKey>(key, _builderNameFormatter(key), _instanceNameFormatter?.Invoke(key));
5151

52-
return _pipelines.GetOrAdd(key, static (_, factory) =>
52+
return _pipelines.GetOrAdd(key, k =>
5353
{
54-
var component = CreatePipelineComponent(factory.instance._activator, factory.context, factory.configure);
54+
var component = new RegistryPipelineComponentBuilder<ResiliencePipelineBuilder<TResult>, TKey>(
55+
_activator,
56+
k,
57+
_builderNameFormatter(k),
58+
_instanceNameFormatter?.Invoke(k),
59+
configure).CreateComponent();
5560

5661
return new ResiliencePipeline<TResult>(component, DisposeBehavior.Reject);
57-
},
58-
(instance: this, context, configure));
62+
});
5963
}
6064

6165
public bool TryAddBuilder(TKey key, Action<ResiliencePipelineBuilder<TResult>, ConfigureBuilderContext<TKey>> configure) => _builders.TryAdd(key, configure);

src/Polly.Core/Registry/ResiliencePipelineRegistry.cs

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.ComponentModel.DataAnnotations;
22
using System.Diagnostics.CodeAnalysis;
3-
using Polly.Telemetry;
43
using Polly.Utils.Pipeline;
54

65
namespace Polly.Registry;
@@ -124,15 +123,17 @@ public ResiliencePipeline GetOrAddPipeline(TKey key, Action<ResiliencePipelineBu
124123
return pipeline;
125124
}
126125

127-
var context = new ConfigureBuilderContext<TKey>(key, _builderNameFormatter(key), _instanceNameFormatter?.Invoke(key));
128-
129-
return _pipelines.GetOrAdd(key, static (_, factory) =>
126+
return _pipelines.GetOrAdd(key, k =>
130127
{
131-
var component = CreatePipelineComponent(factory.instance._activator, factory.context, factory.configure);
128+
var component = new RegistryPipelineComponentBuilder<ResiliencePipelineBuilder, TKey>(
129+
_activator,
130+
k,
131+
_builderNameFormatter(k),
132+
_instanceNameFormatter?.Invoke(k),
133+
configure).CreateComponent();
132134

133135
return new ResiliencePipeline(component, DisposeBehavior.Reject);
134-
},
135-
(instance: this, context, configure));
136+
});
136137
}
137138

138139
/// <summary>
@@ -260,36 +261,6 @@ public async ValueTask DisposeAsync()
260261
}
261262
}
262263

263-
private static PipelineComponent CreatePipelineComponent<TBuilder>(
264-
Func<TBuilder> activator,
265-
ConfigureBuilderContext<TKey> context,
266-
Action<TBuilder, ConfigureBuilderContext<TKey>> configure)
267-
where TBuilder : ResiliencePipelineBuilderBase
268-
{
269-
Func<TBuilder> factory = () =>
270-
{
271-
var builder = activator();
272-
builder.Name = context.BuilderName;
273-
builder.InstanceName = context.BuilderInstanceName;
274-
configure(builder, context);
275-
276-
return builder;
277-
};
278-
279-
var builder = factory();
280-
var pipeline = builder.BuildPipelineComponent();
281-
var telemetry = new ResilienceStrategyTelemetry(
282-
new ResilienceTelemetrySource(context.BuilderName, context.BuilderInstanceName, null),
283-
builder.TelemetryListener);
284-
285-
if (context.ReloadTokenProducer is null)
286-
{
287-
return pipeline;
288-
}
289-
290-
return PipelineComponentFactory.CreateReloadable(pipeline, context.ReloadTokenProducer(), () => factory().BuildPipelineComponent(), telemetry);
291-
}
292-
293264
private GenericRegistry<TResult> GetGenericRegistry<TResult>()
294265
{
295266
if (_genericRegistry.TryGetValue(typeof(TResult), out var genericRegistry))

0 commit comments

Comments
 (0)