Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions src/Polly.Core/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ abstract Polly.Telemetry.TelemetryListener.Write<TResult, TArgs>(in Polly.Teleme
override Polly.Outcome<TResult>.ToString() -> string!
override Polly.Registry.ResiliencePipelineRegistry<TKey>.TryGetPipeline(TKey key, out Polly.ResiliencePipeline? pipeline) -> bool
override Polly.Registry.ResiliencePipelineRegistry<TKey>.TryGetPipeline<TResult>(TKey key, out Polly.ResiliencePipeline<TResult>? pipeline) -> bool
override Polly.ResiliencePropertyKey<TValue>.Equals(object? obj) -> bool
override Polly.ResiliencePropertyKey<TValue>.GetHashCode() -> int
override Polly.ResiliencePropertyKey<TValue>.ToString() -> string!
override Polly.Telemetry.ResilienceEvent.ToString() -> string!
Polly.CircuitBreaker.BrokenCircuitException
Expand Down Expand Up @@ -166,8 +164,6 @@ Polly.PredicateBuilder<TResult>.HandleResult(TResult result, System.Collections.
Polly.PredicateBuilder<TResult>.PredicateBuilder() -> void
Polly.PredicateResult
Polly.Registry.ConfigureBuilderContext<TKey>
Polly.Registry.ConfigureBuilderContext<TKey>.BuilderInstanceName.get -> string?
Polly.Registry.ConfigureBuilderContext<TKey>.BuilderName.get -> string!
Polly.Registry.ConfigureBuilderContext<TKey>.EnableReloads(System.Func<System.Func<System.Threading.CancellationToken>!>! tokenProducerFactory) -> void
Polly.Registry.ConfigureBuilderContext<TKey>.PipelineKey.get -> TKey
Polly.Registry.ResiliencePipelineProvider<TKey>
Expand Down Expand Up @@ -206,11 +202,9 @@ Polly.ResilienceContext.CancellationToken.get -> System.Threading.CancellationTo
Polly.ResilienceContext.ContinueOnCapturedContext.get -> bool
Polly.ResilienceContext.ContinueOnCapturedContext.set -> void
Polly.ResilienceContext.IsSynchronous.get -> bool
Polly.ResilienceContext.IsVoid.get -> bool
Polly.ResilienceContext.OperationKey.get -> string?
Polly.ResilienceContext.Properties.get -> Polly.ResilienceProperties!
Polly.ResilienceContext.ResilienceEvents.get -> System.Collections.Generic.IReadOnlyList<Polly.Telemetry.ResilienceEvent>!
Polly.ResilienceContext.ResultType.get -> System.Type!
Polly.ResilienceContextPool
Polly.ResilienceContextPool.Get(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Polly.ResilienceContext!
Polly.ResilienceContextPool.ResilienceContextPool() -> void
Expand Down Expand Up @@ -268,7 +262,6 @@ Polly.ResilienceProperties.ResilienceProperties() -> void
Polly.ResilienceProperties.Set<TValue>(Polly.ResiliencePropertyKey<TValue> key, TValue value) -> void
Polly.ResilienceProperties.TryGetValue<TValue>(Polly.ResiliencePropertyKey<TValue> key, out TValue value) -> bool
Polly.ResiliencePropertyKey<TValue>
Polly.ResiliencePropertyKey<TValue>.Equals(Polly.ResiliencePropertyKey<TValue> other) -> bool
Polly.ResiliencePropertyKey<TValue>.Key.get -> string!
Polly.ResiliencePropertyKey<TValue>.ResiliencePropertyKey() -> void
Polly.ResiliencePropertyKey<TValue>.ResiliencePropertyKey(string! key) -> void
Expand Down Expand Up @@ -321,9 +314,6 @@ Polly.Retry.RetryStrategyOptions<TResult>.UseJitter.get -> bool
Polly.Retry.RetryStrategyOptions<TResult>.UseJitter.set -> void
Polly.RetryResiliencePipelineBuilderExtensions
Polly.StrategyBuilderContext
Polly.StrategyBuilderContext.BuilderInstanceName.get -> string?
Polly.StrategyBuilderContext.BuilderName.get -> string?
Polly.StrategyBuilderContext.StrategyName.get -> string?
Polly.StrategyBuilderContext.Telemetry.get -> Polly.Telemetry.ResilienceStrategyTelemetry!
Polly.Telemetry.ExecutionAttemptArguments
Polly.Telemetry.ExecutionAttemptArguments.AttemptNumber.get -> int
Expand Down Expand Up @@ -414,8 +404,6 @@ static Polly.ResiliencePipelineBuilderExtensions.AddPipeline<TResult>(this Polly
static Polly.ResiliencePipelineBuilderExtensions.AddStrategy(this Polly.ResiliencePipelineBuilder! builder, System.Func<Polly.StrategyBuilderContext!, Polly.ResilienceStrategy<object!>!>! factory, Polly.ResilienceStrategyOptions! options) -> Polly.ResiliencePipelineBuilder!
static Polly.ResiliencePipelineBuilderExtensions.AddStrategy<TBuilder>(this TBuilder! builder, System.Func<Polly.StrategyBuilderContext!, Polly.ResilienceStrategy!>! factory, Polly.ResilienceStrategyOptions! options) -> TBuilder!
static Polly.ResiliencePipelineBuilderExtensions.AddStrategy<TResult>(this Polly.ResiliencePipelineBuilder<TResult>! builder, System.Func<Polly.StrategyBuilderContext!, Polly.ResilienceStrategy<TResult>!>! factory, Polly.ResilienceStrategyOptions! options) -> Polly.ResiliencePipelineBuilder<TResult>!
static Polly.ResiliencePropertyKey<TValue>.operator !=(Polly.ResiliencePropertyKey<TValue> left, Polly.ResiliencePropertyKey<TValue> right) -> bool
static Polly.ResiliencePropertyKey<TValue>.operator ==(Polly.ResiliencePropertyKey<TValue> left, Polly.ResiliencePropertyKey<TValue> right) -> bool
static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry(this Polly.ResiliencePipelineBuilder! builder, Polly.Retry.RetryStrategyOptions! options) -> Polly.ResiliencePipelineBuilder!
static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry<TResult>(this Polly.ResiliencePipelineBuilder<TResult>! builder, Polly.Retry.RetryStrategyOptions<TResult>! options) -> Polly.ResiliencePipelineBuilder<TResult>!
static Polly.TimeoutResiliencePipelineBuilderExtensions.AddTimeout<TBuilder>(this TBuilder! builder, Polly.Timeout.TimeoutStrategyOptions! options) -> TBuilder!
Expand Down
6 changes: 3 additions & 3 deletions src/Polly.Core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ Pipeline with a single strategy:
var ResiliencePipeline = new ResiliencePipelineBuilder().AddRetry(new()).Build();
```

Pipeline wiht multiple strategies:
Pipeline with multiple strategies:

``` csharp
var ResiliencePipeline = new ResiliencePipelineBuilder()
Expand Down Expand Up @@ -257,7 +257,7 @@ When setting the delegates, ensure to respect the `ResilienceContext.IsSynchrono

## Telemetry

Each individual resilience strategy can emit telemetry by using the [`ResiliencePipelineTelemetry`](Telemetry/ResiliencePipelineTelemetry.cs) API. Polly wraps the arguments as [`TelemetryEventArguments`](Telemetry/TelemetryEventArguments.cs) and emits them using `DiagnosticSource`.
To consume the telemetry, Polly adopters needs to assign an instance of `DiagnosticSource` to `ResiliencePipelineBuilder.DiagnosticSource` and consume `TelemetryEventArguments`.
Each individual resilience strategy can emit telemetry by using the [`ResiliencePipelineTelemetry`](Telemetry/ResiliencePipelineTelemetry.cs) API. Polly wraps the arguments as [`TelemetryEventArguments`](Telemetry/TelemetryEventArguments.cs) and emits them using `TelemetryListener`.
To consume the telemetry, Polly adopters needs to assign an instance of `TelemetryListener` to `ResiliencePipelineBuilder.DiagnosticSource` and consume `TelemetryEventArguments`.

For common use-cases, it is anticipated that Polly users would leverage `Polly.Extensions`. This allows all of the aforementioned functionalities by invoking the `ResiliencePipelineBuilder.ConfigureTelemetry(...)` extension method. `ConfigureTelemetry` processes `TelemetryEventArguments` and generates logs and metrics from it.
6 changes: 3 additions & 3 deletions src/Polly.Core/Registry/ConfigureBuilderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ internal ConfigureBuilderContext(TKey strategyKey, string builderName, string? b
/// <summary>
/// Gets the builder name for the builder being used to create the strategy.
/// </summary>
public string BuilderName { get; }
internal string BuilderName { get; }

/// <summary>
/// Gets the instance name for the builder being used to create the strategy.
/// </summary>
public string? BuilderInstanceName { get; }
internal string? BuilderInstanceName { get; }

internal Func<Func<CancellationToken>>? ReloadTokenProducer { get; private set; }

Expand All @@ -39,7 +39,7 @@ internal ConfigureBuilderContext(TKey strategyKey, string builderName, string? b
/// <param name="tokenProducerFactory">The producer of <see cref="CancellationToken"/> that is triggered when change occurs.</param>
/// <remarks>
/// The <paramref name="tokenProducerFactory"/> should always return function that returns a new <see cref="CancellationToken"/> instance when invoked otherwise
/// the reload infrastructure will stop listening for changes. The <paramref name="tokenProducerFactory"/> is called only once for each streategy.
/// the reload infrastructure will stop listening for changes. The <paramref name="tokenProducerFactory"/> is called only once for each strategy.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public void EnableReloads(Func<Func<CancellationToken>> tokenProducerFactory)
Expand Down
14 changes: 4 additions & 10 deletions src/Polly.Core/Registry/ResiliencePipelineRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,22 +282,16 @@ private static ResiliencePipeline CreatePipeline<TBuilder>(

var builder = factory();
var pipeline = builder.BuildPipeline();
var diagnosticSource = builder.TelemetryListener;
var telemetry = new ResilienceStrategyTelemetry(
new ResilienceTelemetrySource(context.BuilderName, context.BuilderInstanceName, null),
builder.TelemetryListener);

if (context.ReloadTokenProducer is null)
{
return pipeline;
}

return new ReloadableResiliencePipeline(
pipeline,
context.ReloadTokenProducer(),
() => factory().BuildPipeline(),
TelemetryUtil.CreateTelemetry(
diagnosticSource,
context.BuilderName,
context.BuilderInstanceName,
null));
return new ReloadableResiliencePipeline(pipeline, context.ReloadTokenProducer(), () => factory().BuildPipeline(), telemetry);
}

private GenericRegistry<TResult> GetGenericRegistry<TResult>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class ResiliencePipelineRegistryOptions<TKey>
/// </summary>
/// <remarks>
/// Use custom formatter for composite keys in case you want to have different metric values for a builder and strategy key.
/// In general, pipelines can have the same builder name and different pippeline keys.
/// In general, pipelines can have the same builder name and different pipeline keys.
/// </remarks>
/// <value>
/// The default value is a formatter that formats the keys using the <see cref="object.ToString"/> method.
Expand Down
4 changes: 2 additions & 2 deletions src/Polly.Core/ResilienceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ internal ResilienceContext()
/// <summary>
/// Gets the type of the result associated with the execution.
/// </summary>
public Type ResultType { get; private set; } = typeof(UnknownResult);
internal Type ResultType { get; private set; } = typeof(UnknownResult);

/// <summary>
/// Gets a value indicating whether the execution represents a void result.
/// </summary>
public bool IsVoid => ResultType == typeof(VoidResult);
internal bool IsVoid => ResultType == typeof(VoidResult);

/// <summary>
/// Gets or sets a value indicating whether the execution should continue on the captured context.
Expand Down
12 changes: 5 additions & 7 deletions src/Polly.Core/ResiliencePipelineBuilderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,18 @@ internal ResiliencePipeline BuildPipeline()
return NullResiliencePipeline.Instance;
}

var source = new ResilienceTelemetrySource(Name, InstanceName, null);

return CompositeResiliencePipeline.Create(
strategies,
TelemetryUtil.CreateTelemetry(TelemetryListener, Name, InstanceName, null),
new ResilienceStrategyTelemetry(source, TelemetryListener),
TimeProvider);
}

private ResiliencePipeline CreateResiliencePipeline(Entry entry)
{
var context = new StrategyBuilderContext(
builderName: Name,
builderInstanceName: InstanceName,
strategyName: entry.Options.Name,
timeProvider: TimeProvider,
telemetryListener: TelemetryListener);
var source = new ResilienceTelemetrySource(Name, InstanceName, entry.Options.Name);
var context = new StrategyBuilderContext(new ResilienceStrategyTelemetry(source, TelemetryListener), TimeProvider);

var strategy = entry.Factory(context);
strategy.Options = entry.Options;
Expand Down
29 changes: 3 additions & 26 deletions src/Polly.Core/ResiliencePropertyKey.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
namespace Polly;

#pragma warning disable CA1815 // Override equals and operator equals on value types

/// <summary>
/// Represents a key used by <see cref="ResilienceProperties"/>.
/// </summary>
/// <typeparam name="TValue">The type of the value of the property.</typeparam>
public readonly struct ResiliencePropertyKey<TValue> : IEquatable<ResiliencePropertyKey<TValue>>
public readonly struct ResiliencePropertyKey<TValue>
{
/// <summary>
/// Initializes a new instance of the <see cref="ResiliencePropertyKey{TValue}"/> struct.
Expand All @@ -24,30 +26,5 @@ public ResiliencePropertyKey(string key)

/// <inheritdoc/>
public override string ToString() => Key;

/// /// <inheritdoc/>
public override bool Equals(object? obj) => obj is ResiliencePropertyKey<TValue> other && Equals(other);

/// <inheritdoc/>
public bool Equals(ResiliencePropertyKey<TValue> other) => StringComparer.Ordinal.Equals(Key, other.Key);

/// <inheritdoc/>
public override int GetHashCode() => (StringComparer.Ordinal.GetHashCode(Key), typeof(TValue)).GetHashCode();

/// <summary>
/// The operator to compare two instances of <see cref="ResiliencePropertyKey{TValue}"/> for equality.
/// </summary>
/// <param name="left">The left instance.</param>
/// <param name="right">The right instance.</param>
/// <returns>True if the instances are equal, false otherwise.</returns>
public static bool operator ==(ResiliencePropertyKey<TValue> left, ResiliencePropertyKey<TValue> right) => left.Equals(right);

/// <summary>
/// The operator to compare two instances of <see cref="ResiliencePropertyKey{TValue}"/> for inequality.
/// </summary>
/// <param name="left">The left instance.</param>
/// <param name="right">The right instance.</param>
/// <returns>True if the instances are not equal, false otherwise.</returns>
public static bool operator !=(ResiliencePropertyKey<TValue> left, ResiliencePropertyKey<TValue> right) => !(left == right);
}

27 changes: 2 additions & 25 deletions src/Polly.Core/StrategyBuilderContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,12 @@ namespace Polly;
/// </summary>
public sealed class StrategyBuilderContext
{
internal StrategyBuilderContext(
string? builderName,
string? builderInstanceName,
string? strategyName,
TimeProvider timeProvider,
TelemetryListener? telemetryListener)
internal StrategyBuilderContext(ResilienceStrategyTelemetry telemetry, TimeProvider timeProvider)
{
BuilderName = builderName;
BuilderInstanceName = builderInstanceName;
StrategyName = strategyName;
TimeProvider = timeProvider;
Telemetry = TelemetryUtil.CreateTelemetry(telemetryListener, builderName, builderInstanceName, strategyName);
Telemetry = telemetry;
}

/// <summary>
/// Gets the name of the builder.
/// </summary>
public string? BuilderName { get; }

/// <summary>
/// Gets the instance name of the builder.
/// </summary>
public string? BuilderInstanceName { get; }

/// <summary>
/// Gets the name of the strategy.
/// </summary>
public string? StrategyName { get; }

/// <summary>
/// Gets the resilience telemetry used to report important events.
/// </summary>
Expand Down
11 changes: 0 additions & 11 deletions src/Polly.Core/Telemetry/TelemetryUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,6 @@ internal static class TelemetryUtil

internal const string PipelineExecuted = "PipelineExecuted";

public static ResilienceStrategyTelemetry CreateTelemetry(
TelemetryListener? listener,
string? builderName,
string? builderInstanceName,
string? strategyName)
{
var telemetrySource = new ResilienceTelemetrySource(builderName, builderInstanceName, strategyName);

return new ResilienceStrategyTelemetry(telemetrySource, listener);
}

public static void ReportExecutionAttempt<TResult>(
ResilienceStrategyTelemetry telemetry,
ResilienceContext context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,12 @@ internal AddResiliencePipelineContext(ConfigureBuilderContext<TKey> registryCont
{
RegistryContext = registryContext;
ServiceProvider = serviceProvider;
PipelineKey = registryContext.PipelineKey;
BuilderName = registryContext.BuilderName;
}

/// <summary>
/// Gets the strategy key for the strategy being created.
/// Gets the pipeline key for the pipeline being created.
/// </summary>
public string BuilderName { get; }

/// <summary>
/// Gets the strategy key for the strategy being created.
/// </summary>
public TKey PipelineKey { get; }
public TKey PipelineKey => RegistryContext.PipelineKey;

/// <summary>
/// Gets the <see cref="IServiceProvider"/> that provides access to the dependency injection container.
Expand Down
1 change: 0 additions & 1 deletion src/Polly.Extensions/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#nullable enable
abstract Polly.Telemetry.MeteringEnricher.Enrich<TResult, TArgs>(in Polly.Telemetry.EnrichmentContext<TResult, TArgs> context) -> void
Polly.DependencyInjection.AddResiliencePipelineContext<TKey>
Polly.DependencyInjection.AddResiliencePipelineContext<TKey>.BuilderName.get -> string!
Polly.DependencyInjection.AddResiliencePipelineContext<TKey>.EnableReloads<TOptions>(string? name = null) -> void
Polly.DependencyInjection.AddResiliencePipelineContext<TKey>.GetOptions<TOptions>(string? name = null) -> TOptions
Polly.DependencyInjection.AddResiliencePipelineContext<TKey>.PipelineKey.get -> TKey
Expand Down
Loading