diff --git a/bench/Polly.Core.Benchmarks/BridgeBenchmark.cs b/bench/Polly.Core.Benchmarks/BridgeBenchmark.cs index afb19561cc9..68499284542 100644 --- a/bench/Polly.Core.Benchmarks/BridgeBenchmark.cs +++ b/bench/Polly.Core.Benchmarks/BridgeBenchmark.cs @@ -9,7 +9,7 @@ public class BridgeBenchmark public void Setup() { _policy = Policy.NoOpAsync(); - _policyWrapped = ResiliencePipeline.Null.AsAsyncPolicy(); + _policyWrapped = ResiliencePipeline.Empty.AsAsyncPolicy(); } [Benchmark(Baseline = true)] diff --git a/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs b/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs index b154af10223..55bea8960cb 100644 --- a/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs +++ b/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs @@ -10,7 +10,7 @@ public class ResiliencePipelineBenchmark public async ValueTask ExecuteOutcomeAsync() { var context = ResilienceContextPool.Shared.Get(); - await ResiliencePipeline.Null.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false); + await ResiliencePipeline.Empty.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false); ResilienceContextPool.Shared.Return(context); } @@ -18,40 +18,40 @@ public async ValueTask ExecuteOutcomeAsync() public async ValueTask ExecuteAsync_ResilienceContextAndState() { var context = ResilienceContextPool.Shared.Get(); - await ResiliencePipeline.Null.ExecuteAsync((_, _) => new ValueTask("dummy"), context, "state").ConfigureAwait(false); + await ResiliencePipeline.Empty.ExecuteAsync((_, _) => new ValueTask("dummy"), context, "state").ConfigureAwait(false); ResilienceContextPool.Shared.Return(context); } [Benchmark] public async ValueTask ExecuteAsync_CancellationToken() { - await ResiliencePipeline.Null.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); + await ResiliencePipeline.Empty.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); } [Benchmark] public async ValueTask ExecuteAsync_GenericStrategy_CancellationToken() { - await ResiliencePipeline.Null.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); + await ResiliencePipeline.Empty.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); } [Benchmark] public void Execute_ResilienceContextAndState() { var context = ResilienceContextPool.Shared.Get(); - ResiliencePipeline.Null.Execute((_, _) => "dummy", context, "state"); + ResiliencePipeline.Empty.Execute((_, _) => "dummy", context, "state"); ResilienceContextPool.Shared.Return(context); } [Benchmark] public void Execute_CancellationToken() { - ResiliencePipeline.Null.Execute(_ => "dummy", CancellationToken.None); + ResiliencePipeline.Empty.Execute(_ => "dummy", CancellationToken.None); } [Benchmark] public void Execute_GenericStrategy_CancellationToken() { - ResiliencePipeline.Null.Execute(_ => "dummy", CancellationToken.None); + ResiliencePipeline.Empty.Execute(_ => "dummy", CancellationToken.None); } public class NonGenericStrategy diff --git a/src/Polly.Core/Hedging/Controller/HedgingExecutionContext.cs b/src/Polly.Core/Hedging/Controller/HedgingExecutionContext.cs index c55641783f3..b3ac6a9ab6f 100644 --- a/src/Polly.Core/Hedging/Controller/HedgingExecutionContext.cs +++ b/src/Polly.Core/Hedging/Controller/HedgingExecutionContext.cs @@ -207,14 +207,6 @@ private void UpdateOriginalContext() if (Tasks.FirstOrDefault(static t => t.IsAccepted) is TaskExecution acceptedExecution) { originalContext.Properties.Replace(acceptedExecution.Properties); - - if (acceptedExecution.Type == HedgedTaskType.Secondary) - { - foreach (var @event in acceptedExecution.Context.ResilienceEvents) - { - originalContext.AddResilienceEvent(@event); - } - } } } diff --git a/src/Polly.Core/Outcome.TResult.cs b/src/Polly.Core/Outcome.TResult.cs index 21e1c337426..abd8d9a64ba 100644 --- a/src/Polly.Core/Outcome.TResult.cs +++ b/src/Polly.Core/Outcome.TResult.cs @@ -44,12 +44,12 @@ private Outcome(ExceptionDispatchInfo exceptionDispatchInfo) /// /// Returns even if the result is void. Use to check for void results. /// - public bool HasResult => ExceptionDispatchInfo is null; + internal bool HasResult => ExceptionDispatchInfo is null; /// /// Gets a value indicating whether the operation produced a void result. /// - public bool IsVoidResult => Result is VoidResult; + internal bool IsVoidResult => Result is VoidResult; /// /// Throws an exception if the operation produced an exception. @@ -64,7 +64,7 @@ private Outcome(ExceptionDispatchInfo exceptionDispatchInfo) /// /// Output parameter for the result. /// if the result is available; otherwise. - public bool TryGetResult(out TResult? result) + internal bool TryGetResult(out TResult? result) { if (HasResult && !IsVoidResult) { diff --git a/src/Polly.Core/PublicAPI.Unshipped.txt b/src/Polly.Core/PublicAPI.Unshipped.txt index c8af645ea81..5106f7f5677 100644 --- a/src/Polly.Core/PublicAPI.Unshipped.txt +++ b/src/Polly.Core/PublicAPI.Unshipped.txt @@ -134,11 +134,8 @@ Polly.Outcome Polly.Outcome Polly.Outcome.EnsureSuccess() -> void Polly.Outcome.Exception.get -> System.Exception? -Polly.Outcome.HasResult.get -> bool -Polly.Outcome.IsVoidResult.get -> bool Polly.Outcome.Outcome() -> void Polly.Outcome.Result.get -> TResult? -Polly.Outcome.TryGetResult(out TResult? result) -> bool Polly.OutcomeArguments Polly.OutcomeArguments.Arguments.get -> TArgs Polly.OutcomeArguments.Context.get -> Polly.ResilienceContext! @@ -193,7 +190,6 @@ Polly.ResilienceContext.CancellationToken.get -> System.Threading.CancellationTo Polly.ResilienceContext.ContinueOnCapturedContext.get -> bool Polly.ResilienceContext.OperationKey.get -> string? Polly.ResilienceContext.Properties.get -> Polly.ResilienceProperties! -Polly.ResilienceContext.ResilienceEvents.get -> System.Collections.Generic.IReadOnlyList! Polly.ResilienceContextCreationArguments Polly.ResilienceContextCreationArguments.CancellationToken.get -> System.Threading.CancellationToken Polly.ResilienceContextCreationArguments.ContinueOnCapturedContext.get -> bool? @@ -406,7 +402,7 @@ static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry(this Polly.Resili static Polly.RetryResiliencePipelineBuilderExtensions.AddRetry(this Polly.ResiliencePipelineBuilder! builder, Polly.Retry.RetryStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! static Polly.TimeoutResiliencePipelineBuilderExtensions.AddTimeout(this TBuilder! builder, Polly.Timeout.TimeoutStrategyOptions! options) -> TBuilder! static Polly.TimeoutResiliencePipelineBuilderExtensions.AddTimeout(this TBuilder! builder, System.TimeSpan timeout) -> TBuilder! -static readonly Polly.ResiliencePipeline.Null -> Polly.ResiliencePipeline! -static readonly Polly.ResiliencePipeline.Null -> Polly.ResiliencePipeline! +static readonly Polly.ResiliencePipeline.Empty -> Polly.ResiliencePipeline! +static readonly Polly.ResiliencePipeline.Empty -> Polly.ResiliencePipeline! virtual Polly.Registry.ResiliencePipelineProvider.GetPipeline(TKey key) -> Polly.ResiliencePipeline! virtual Polly.Registry.ResiliencePipelineProvider.GetPipeline(TKey key) -> Polly.ResiliencePipeline! diff --git a/src/Polly.Core/ResilienceContext.cs b/src/Polly.Core/ResilienceContext.cs index 09fe070f7ca..d386b460bb0 100644 --- a/src/Polly.Core/ResilienceContext.cs +++ b/src/Polly.Core/ResilienceContext.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using Polly.Telemetry; namespace Polly; @@ -14,8 +13,6 @@ namespace Polly; /// public sealed class ResilienceContext { - private readonly List _resilienceEvents = new(); - internal ResilienceContext() { } @@ -66,15 +63,6 @@ internal ResilienceContext() /// public ResilienceProperties Properties { get; internal set; } = new(); - /// - /// Gets the collection of resilience events that occurred while executing the resilience strategy. - /// - /// - /// If the number of resilience events with severity greater than is greater than zero it's an indication that the execution was unhealthy. - /// Note that the number of reported events depends on whether telemetry is enabled for the pipeline or not. - /// - public IReadOnlyList ResilienceEvents => _resilienceEvents; - internal void InitializeFrom(ResilienceContext context) { OperationKey = context.OperationKey; @@ -82,8 +70,6 @@ internal void InitializeFrom(ResilienceContext context) IsSynchronous = context.IsSynchronous; CancellationToken = context.CancellationToken; ContinueOnCapturedContext = context.ContinueOnCapturedContext; - _resilienceEvents.Clear(); - _resilienceEvents.AddRange(context.ResilienceEvents); } [ExcludeFromCodeCoverage] @@ -101,11 +87,6 @@ internal ResilienceContext Initialize(bool isSynchronous) return this; } - internal void AddResilienceEvent(ResilienceEvent @event) - { - _resilienceEvents.Add(@event); - } - internal bool Reset() { OperationKey = null; @@ -114,7 +95,6 @@ internal bool Reset() ContinueOnCapturedContext = false; CancellationToken = default; Properties.Options.Clear(); - _resilienceEvents.Clear(); return true; } diff --git a/src/Polly.Core/ResiliencePipeline.cs b/src/Polly.Core/ResiliencePipeline.cs index b6535fbf63b..fa3f06e202b 100644 --- a/src/Polly.Core/ResiliencePipeline.cs +++ b/src/Polly.Core/ResiliencePipeline.cs @@ -14,7 +14,7 @@ public sealed partial class ResiliencePipeline /// /// Resilience pipeline that executes the user-provided callback without any additional logic. /// - public static readonly ResiliencePipeline Null = new(PipelineComponent.Null, DisposeBehavior.Ignore); + public static readonly ResiliencePipeline Empty = new(PipelineComponent.Empty, DisposeBehavior.Ignore); internal ResiliencePipeline(PipelineComponent component, DisposeBehavior disposeBehavior) { diff --git a/src/Polly.Core/ResiliencePipelineBuilderBase.cs b/src/Polly.Core/ResiliencePipelineBuilderBase.cs index 738e6df5485..a8eb81bba85 100644 --- a/src/Polly.Core/ResiliencePipelineBuilderBase.cs +++ b/src/Polly.Core/ResiliencePipelineBuilderBase.cs @@ -114,7 +114,7 @@ internal PipelineComponent BuildPipelineComponent() if (components.Count == 0) { - return PipelineComponent.Null; + return PipelineComponent.Empty; } var source = new ResilienceTelemetrySource(Name, InstanceName, null); diff --git a/src/Polly.Core/ResiliencePipelineT.cs b/src/Polly.Core/ResiliencePipelineT.cs index 5b96106ec64..6c6433dde29 100644 --- a/src/Polly.Core/ResiliencePipelineT.cs +++ b/src/Polly.Core/ResiliencePipelineT.cs @@ -15,7 +15,7 @@ public sealed partial class ResiliencePipeline /// /// Resilience pipeline that executes the user-provided callback without any additional logic. /// - public static readonly ResiliencePipeline Null = new(PipelineComponent.Null, DisposeBehavior.Ignore); + public static readonly ResiliencePipeline Empty = new(PipelineComponent.Empty, DisposeBehavior.Ignore); internal ResiliencePipeline(PipelineComponent component, DisposeBehavior disposeBehavior) { diff --git a/src/Polly.Core/Telemetry/ResilienceStrategyTelemetry.cs b/src/Polly.Core/Telemetry/ResilienceStrategyTelemetry.cs index 12d9b535cbb..17538f28fc3 100644 --- a/src/Polly.Core/Telemetry/ResilienceStrategyTelemetry.cs +++ b/src/Polly.Core/Telemetry/ResilienceStrategyTelemetry.cs @@ -33,8 +33,6 @@ public void Report(ResilienceEvent resilienceEvent, ResilienceContext con { Guard.NotNull(context); - context.AddResilienceEvent(resilienceEvent); - if (Listener is null || resilienceEvent.Severity == ResilienceEventSeverity.None) { return; @@ -52,8 +50,6 @@ public void Report(ResilienceEvent resilienceEvent, ResilienceContext con /// The event arguments. public void Report(ResilienceEvent resilienceEvent, OutcomeArguments args) { - args.Context.AddResilienceEvent(resilienceEvent); - if (Listener is null || resilienceEvent.Severity == ResilienceEventSeverity.None) { return; diff --git a/src/Polly.Core/Utils/Pipeline/PipelineComponent.cs b/src/Polly.Core/Utils/Pipeline/PipelineComponent.cs index f19236fe22f..d790f58ac52 100644 --- a/src/Polly.Core/Utils/Pipeline/PipelineComponent.cs +++ b/src/Polly.Core/Utils/Pipeline/PipelineComponent.cs @@ -8,7 +8,7 @@ /// internal abstract class PipelineComponent : IDisposable, IAsyncDisposable { - public static PipelineComponent Null { get; } = new NullComponent(); + public static PipelineComponent Empty { get; } = new NullComponent(); internal ResilienceStrategyOptions? Options { get; set; } diff --git a/src/Polly.Extensions/README.md b/src/Polly.Extensions/README.md index 82355384a7e..83b25375c44 100644 --- a/src/Polly.Extensions/README.md +++ b/src/Polly.Extensions/README.md @@ -130,7 +130,6 @@ Dimensions: |`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.| |`operation-key`| The operation key associated with the call site. | |`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). | -|`execution-health`| Indicates whether the execution was healthy or not (`Healthy`, `Unhealthy`). | ### Logs diff --git a/src/Polly.Extensions/Telemetry/Log.cs b/src/Polly.Extensions/Telemetry/Log.cs index 1d2805c9849..49a21a95e1a 100644 --- a/src/Polly.Extensions/Telemetry/Log.cs +++ b/src/Polly.Extensions/Telemetry/Log.cs @@ -46,7 +46,6 @@ public static partial void PipelineExecuting( "Source: '{PipelineName}/{PipelineInstance}', " + "Operation Key: '{OperationKey}', " + "Result: '{Result}', " + - "Execution Health: '{ExecutionHealth}', " + "Execution Time: {ExecutionTime}ms", EventName = "StrategyExecuted")] public static partial void PipelineExecuted( @@ -56,7 +55,6 @@ public static partial void PipelineExecuted( string pipelineInstance, string? operationKey, object? result, - string executionHealth, double executionTime, Exception? exception); diff --git a/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs b/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs deleted file mode 100644 index 60fc606efd2..00000000000 --- a/src/Polly.Extensions/Telemetry/ResilienceContextExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Polly.Telemetry; - -internal static class ResilienceContextExtensions -{ - public static string GetExecutionHealth(this ResilienceContext context) => context.IsExecutionHealthy() ? "Healthy" : "Unhealthy"; - - public static bool IsExecutionHealthy(this ResilienceContext context) - { - for (int i = 0; i < context.ResilienceEvents.Count; i++) - { - if (context.ResilienceEvents[i].Severity > ResilienceEventSeverity.Information) - { - return false; - } - } - - return true; - } -} diff --git a/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs b/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs index acf901b0f1d..9e627d9597f 100644 --- a/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs +++ b/src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs @@ -16,8 +16,6 @@ internal class ResilienceTelemetryTags public const string ExceptionName = "exception-name"; - public const string ExecutionHealth = "execution-health"; - public const string AttemptNumber = "attempt-number"; public const string AttemptHandled = "attempt-handled"; diff --git a/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs b/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs index 28bf79e0e8c..864211d6ed3 100644 --- a/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs +++ b/src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs @@ -109,7 +109,6 @@ private void MeterEvent(in TelemetryEventArguments(in args, tags.Tags); UpdateEnrichmentContext(in context); - tags.Tags.Add(new(ResilienceTelemetryTags.ExecutionHealth, args.Context.GetExecutionHealth())); ExecutionDuration.Record(executionFinished.Duration.TotalMilliseconds, tags.TagsSpan); TagsList.Return(tags); } @@ -165,15 +164,12 @@ private void LogEvent(in TelemetryEventArguments } else if (GetArgs(args.Arguments, out var pipelineExecuted)) { - var logLevel = args.Context.IsExecutionHealthy() ? LogLevel.Debug : LogLevel.Warning; - _logger.PipelineExecuted( - logLevel, + LogLevel.Debug, args.Source.PipelineName.GetValueOrPlaceholder(), args.Source.PipelineInstanceName.GetValueOrPlaceholder(), args.Context.OperationKey, GetResult(args.Context, args.Outcome), - args.Context.GetExecutionHealth(), pipelineExecuted.Duration.TotalMilliseconds, args.Outcome?.Exception); } diff --git a/src/Polly.RateLimiting/OnRateLimiterRejectedArguments.cs b/src/Polly.RateLimiting/OnRateLimiterRejectedArguments.cs index 7e6eb91cc11..072b249ab4b 100644 --- a/src/Polly.RateLimiting/OnRateLimiterRejectedArguments.cs +++ b/src/Polly.RateLimiting/OnRateLimiterRejectedArguments.cs @@ -17,12 +17,10 @@ public readonly struct OnRateLimiterRejectedArguments /// /// The context associated with the execution of a user-provided callback. /// The lease that has no permits and was rejected by the rate limiter. - /// The amount of time to wait before retrying again. - public OnRateLimiterRejectedArguments(ResilienceContext context, RateLimitLease lease, TimeSpan? retryAfter) + public OnRateLimiterRejectedArguments(ResilienceContext context, RateLimitLease lease) { Context = context; Lease = lease; - RetryAfter = retryAfter; } /// @@ -34,12 +32,4 @@ public OnRateLimiterRejectedArguments(ResilienceContext context, RateLimitLease /// Gets the lease that has no permits and was rejected by the rate limiter. /// public RateLimitLease Lease { get; } - - /// - /// Gets the amount of time to wait before retrying again. - /// - /// - /// This value is retrieved from the by reading the . - /// - public TimeSpan? RetryAfter { get; } } diff --git a/src/Polly.RateLimiting/PublicAPI.Unshipped.txt b/src/Polly.RateLimiting/PublicAPI.Unshipped.txt index d6e66991924..ad59951f733 100644 --- a/src/Polly.RateLimiting/PublicAPI.Unshipped.txt +++ b/src/Polly.RateLimiting/PublicAPI.Unshipped.txt @@ -4,8 +4,7 @@ Polly.RateLimiting.OnRateLimiterRejectedArguments Polly.RateLimiting.OnRateLimiterRejectedArguments.Context.get -> Polly.ResilienceContext! Polly.RateLimiting.OnRateLimiterRejectedArguments.Lease.get -> System.Threading.RateLimiting.RateLimitLease! Polly.RateLimiting.OnRateLimiterRejectedArguments.OnRateLimiterRejectedArguments() -> void -Polly.RateLimiting.OnRateLimiterRejectedArguments.OnRateLimiterRejectedArguments(Polly.ResilienceContext! context, System.Threading.RateLimiting.RateLimitLease! lease, System.TimeSpan? retryAfter) -> void -Polly.RateLimiting.OnRateLimiterRejectedArguments.RetryAfter.get -> System.TimeSpan? +Polly.RateLimiting.OnRateLimiterRejectedArguments.OnRateLimiterRejectedArguments(Polly.ResilienceContext! context, System.Threading.RateLimiting.RateLimitLease! lease) -> void Polly.RateLimiting.RateLimiterRejectedException Polly.RateLimiting.RateLimiterRejectedException.RateLimiterRejectedException() -> void Polly.RateLimiting.RateLimiterRejectedException.RateLimiterRejectedException(string! message) -> void diff --git a/src/Polly.RateLimiting/RateLimiterResilienceStrategy.cs b/src/Polly.RateLimiting/RateLimiterResilienceStrategy.cs index 59274c95e98..80301b9e430 100644 --- a/src/Polly.RateLimiting/RateLimiterResilienceStrategy.cs +++ b/src/Polly.RateLimiting/RateLimiterResilienceStrategy.cs @@ -45,12 +45,12 @@ protected override async ValueTask> ExecuteCore _options = new(); private readonly CircuitBehavior _circuitBehavior = Substitute.For(); - private readonly Action> _onTelemetry = _ => { }; + private readonly FakeTelemetryListener _telemetryListener = new(); [Fact] public void Ctor_EnsureDefaults() @@ -60,7 +59,7 @@ public async Task IsolateAsync_Ok() await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); _circuitBehavior.Received().OnCircuitClosed(); - context.ResilienceEvents.Should().Contain(new ResilienceEvent(ResilienceEventSeverity.Error, "OnCircuitOpened")); + _telemetryListener.GetArgs().Should().NotBeEmpty(); } [Fact] @@ -93,7 +92,7 @@ public async Task BreakAsync_Ok() await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); _circuitBehavior.Received().OnCircuitClosed(); - context.ResilienceEvents.Should().Contain(new ResilienceEvent(ResilienceEventSeverity.Information, "OnCircuitClosed")); + _telemetryListener.GetArgs().Should().NotBeEmpty(); } [Fact] @@ -467,5 +466,5 @@ private async Task OpenCircuit(CircuitStateController controller, Outcome { args.ActionContext.Properties.Set(new ResiliencePropertyKey(attempt.ToString(CultureInfo.InvariantCulture)), attempt); diff --git a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs index 855e91772c8..98b1f6e7120 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs @@ -912,8 +912,8 @@ public async Task ExecuteAsync_EnsureOnHedgingTelemetry() var strategy = Create(); await strategy.ExecuteAsync((_, _) => new ValueTask(Failure), context, "state"); - context.ResilienceEvents.Should().HaveCount(_options.MaxHedgedAttempts + 1); - context.ResilienceEvents.Select(v => v.EventName).Distinct().Should().HaveCount(2); + _events.Should().HaveCount(_options.MaxHedgedAttempts + 4); + _events.Select(v => v.Event.EventName).Distinct().Should().HaveCount(2); } private void ConfigureHedging() diff --git a/test/Polly.Core.Tests/Registry/ResiliencePipelineProviderTests.cs b/test/Polly.Core.Tests/Registry/ResiliencePipelineProviderTests.cs index 5adcc497df5..2872d1f53ac 100644 --- a/test/Polly.Core.Tests/Registry/ResiliencePipelineProviderTests.cs +++ b/test/Polly.Core.Tests/Registry/ResiliencePipelineProviderTests.cs @@ -37,7 +37,7 @@ public void Get_Exist_Ok() [Fact] public void Get_GenericExist_Ok() { - var provider = new Provider { GenericStrategy = ResiliencePipeline.Null }; + var provider = new Provider { GenericStrategy = ResiliencePipeline.Empty }; provider.GetPipeline("exists").Should().Be(provider.GenericStrategy); } diff --git a/test/Polly.Core.Tests/ResilienceContextPoolTests.cs b/test/Polly.Core.Tests/ResilienceContextPoolTests.cs index 5f0da0f73f6..8ca11663d13 100644 --- a/test/Polly.Core.Tests/ResilienceContextPoolTests.cs +++ b/test/Polly.Core.Tests/ResilienceContextPoolTests.cs @@ -1,5 +1,3 @@ -using Polly.Telemetry; - namespace Polly.Core.Tests; public class ResilienceContextPoolTests @@ -113,7 +111,6 @@ await TestUtilities.AssertWithTimeoutAsync(() => context.Initialize(true); context.CancellationToken.Should().Be(cts.Token); context.Properties.Set(new ResiliencePropertyKey("abc"), 10); - context.AddResilienceEvent(new ResilienceEvent(ResilienceEventSeverity.Information, "dummy")); ResilienceContextPool.Shared.Return(context); AssertDefaults(context); @@ -129,7 +126,6 @@ private static void AssertDefaults(ResilienceContext context) context.IsSynchronous.Should().BeFalse(); context.CancellationToken.Should().Be(CancellationToken.None); context.Properties.Options.Should().BeEmpty(); - context.ResilienceEvents.Should().BeEmpty(); context.OperationKey.Should().BeNull(); } } diff --git a/test/Polly.Core.Tests/ResilienceContextTests.cs b/test/Polly.Core.Tests/ResilienceContextTests.cs index b8a2b089edd..1dee2e62355 100644 --- a/test/Polly.Core.Tests/ResilienceContextTests.cs +++ b/test/Polly.Core.Tests/ResilienceContextTests.cs @@ -1,20 +1,7 @@ -using Polly.Telemetry; - namespace Polly.Core.Tests; public class ResilienceContextTests { - [Fact] - public void AddResilienceEvent_Ok() - { - var context = ResilienceContextPool.Shared.Get(); - - context.AddResilienceEvent(new ResilienceEvent(ResilienceEventSeverity.Information, "Dummy")); - - context.ResilienceEvents.Should().HaveCount(1); - context.ResilienceEvents.Should().Contain(new ResilienceEvent(ResilienceEventSeverity.Information, "Dummy")); - } - [InlineData(true)] [InlineData(false)] [Theory] diff --git a/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs b/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs index f6fd84728e0..7bc0ec3cffa 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs @@ -108,8 +108,8 @@ public void AddPipeline_Duplicate_Throws() // arrange var executions = new List(); var builder = new ResiliencePipelineBuilder() - .AddPipeline(ResiliencePipeline.Null) - .AddPipeline(ResiliencePipeline.Null); + .AddPipeline(ResiliencePipeline.Empty) + .AddPipeline(ResiliencePipeline.Empty); builder.Invoking(b => b.Build()) .Should() @@ -174,7 +174,7 @@ public void AddPipeline_MultipleNonDelegating_Ok() } [Fact] - public void Build_Empty_ReturnsNullResiliencePipeline() => new ResiliencePipelineBuilder().Build().Component.Should().BeSameAs(PipelineComponent.Null); + public void Build_Empty_ReturnsNullResiliencePipeline() => new ResiliencePipelineBuilder().Build().Component.Should().BeSameAs(PipelineComponent.Empty); [Fact] public void AddPipeline_AfterUsed_Throws() @@ -184,7 +184,7 @@ public void AddPipeline_AfterUsed_Throws() builder.Build(); builder - .Invoking(b => b.AddPipeline(ResiliencePipeline.Null)) + .Invoking(b => b.AddPipeline(ResiliencePipeline.Empty)) .Should() .Throw() .WithMessage("Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once."); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs index 57b172c9848..27dcd6a46b9 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs @@ -82,7 +82,7 @@ public async Task ExecuteAsync_GenericStrategy_Ok(Func.Null.ExecuteOutcomeAsync((context, state) => + var result = await ResiliencePipeline.Empty.ExecuteOutcomeAsync((context, state) => { state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs index c79459f8837..1ae26be6741 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs @@ -117,7 +117,7 @@ static async ValueTask AssertStackTrace(Func + var result = await ResiliencePipeline.Empty.ExecuteOutcomeAsync((context, state) => { state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.cs index 2cb06a360b3..616d6728128 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.cs @@ -13,23 +13,23 @@ public partial class ResiliencePipelineTests [Fact] public async Task Dispose_NullPipeline_OK() { - ResiliencePipeline.Null.DisposeHelper.Dispose(); - ResiliencePipeline.Null.DisposeHelper.Dispose(); - await ResiliencePipeline.Null.DisposeHelper.DisposeAsync(); - await ResiliencePipeline.Null.DisposeHelper.DisposeAsync(); + ResiliencePipeline.Empty.DisposeHelper.Dispose(); + ResiliencePipeline.Empty.DisposeHelper.Dispose(); + await ResiliencePipeline.Empty.DisposeHelper.DisposeAsync(); + await ResiliencePipeline.Empty.DisposeHelper.DisposeAsync(); - ResiliencePipeline.Null.Execute(() => 1).Should().Be(1); + ResiliencePipeline.Empty.Execute(() => 1).Should().Be(1); } [Fact] public async Task Dispose_NullGenericPipeline_OK() { - ResiliencePipeline.Null.DisposeHelper.Dispose(); - ResiliencePipeline.Null.DisposeHelper.Dispose(); - await ResiliencePipeline.Null.DisposeHelper.DisposeAsync(); - await ResiliencePipeline.Null.DisposeHelper.DisposeAsync(); + ResiliencePipeline.Empty.DisposeHelper.Dispose(); + ResiliencePipeline.Empty.DisposeHelper.Dispose(); + await ResiliencePipeline.Empty.DisposeHelper.DisposeAsync(); + await ResiliencePipeline.Empty.DisposeHelper.DisposeAsync(); - ResiliencePipeline.Null.Execute(() => 1).Should().Be(1); + ResiliencePipeline.Empty.Execute(() => 1).Should().Be(1); } [Fact] @@ -78,8 +78,8 @@ public async Task DisposeAsync_Allowed_Disposed() [Fact] public void Null_Ok() { - ResiliencePipeline.Null.Should().NotBeNull(); - ResiliencePipeline.Null.Should().NotBeNull(); + ResiliencePipeline.Empty.Should().NotBeNull(); + ResiliencePipeline.Empty.Should().NotBeNull(); } [Fact] diff --git a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs index 9492e585e90..324952e67bc 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs @@ -68,9 +68,9 @@ public void Create_EnsurePipelineReusableAcrossDifferentPipelines() var pipeline = CreateSut(components); - CreateSut(new PipelineComponent[] { PipelineComponent.Null, pipeline }); + CreateSut(new PipelineComponent[] { PipelineComponent.Empty, pipeline }); - this.Invoking(_ => CreateSut(new PipelineComponent[] { PipelineComponent.Null, pipeline })) + this.Invoking(_ => CreateSut(new PipelineComponent[] { PipelineComponent.Empty, pipeline })) .Should() .NotThrow(); } @@ -126,22 +126,6 @@ public void ExecutePipeline_EnsureTelemetryArgumentsReported() _listener.GetArgs().Should().HaveCount(1); } - [Fact] - public void ExecutePipeline_TelemetryNotEnabled_NoEventsReported() - { - var component = PipelineComponentFactory.CreateComposite( - new[] { Substitute.For() }, - new ResilienceStrategyTelemetry(_telemetry.TelemetrySource, null), - Substitute.For()); - - var pipeline = new ResiliencePipeline(component, DisposeBehavior.Allow); - var context = ResilienceContextPool.Shared.Get(); - - pipeline.Execute(_ => { }, context); - - context.ResilienceEvents.Should().BeEmpty(); - } - [Fact] public void Dispose_EnsureInnerComponentsDisposed() { diff --git a/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentTests.cs index e7b79aecbcb..41d4f01d1c2 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/PipelineComponentTests.cs @@ -8,8 +8,8 @@ public class PipelineComponentTests [Fact] public async Task Dispose_Ok() { - PipelineComponent.Null.Should().NotBeNull(); - PipelineComponent.Null.Dispose(); - await PipelineComponent.Null.DisposeAsync(); + PipelineComponent.Empty.Should().NotBeNull(); + PipelineComponent.Empty.Dispose(); + await PipelineComponent.Empty.DisposeAsync(); } } diff --git a/test/Polly.Core.Tests/Utils/Pipeline/ReloadablePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/ReloadablePipelineComponentTests.cs index 59f3eafec9f..55b8dc98ac7 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/ReloadablePipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/ReloadablePipelineComponentTests.cs @@ -111,9 +111,9 @@ public void ChangeTriggered_FactoryError_LastStrategyUsedAndErrorReported() private ReloadableComponent CreateSut(PipelineComponent? initial = null, Func? factory = null) { - factory ??= () => PipelineComponent.Null; + factory ??= () => PipelineComponent.Empty; - return (ReloadableComponent)PipelineComponentFactory.CreateReloadable(initial ?? PipelineComponent.Null, + return (ReloadableComponent)PipelineComponentFactory.CreateReloadable(initial ?? PipelineComponent.Empty, () => _cancellationTokenSource.Token, factory, _telemetry); diff --git a/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs b/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs index 5ce67a3266c..214cf32b724 100644 --- a/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs +++ b/test/Polly.Extensions.Tests/Telemetry/TelemetryListenerImplTests.cs @@ -347,24 +347,16 @@ public void OnTelemetryEvent_Ok(bool hasCallback) called.Should().Be(hasCallback); } - [InlineData(true, false)] - [InlineData(false, false)] - [InlineData(true, true)] - [InlineData(false, true)] + [InlineData(true)] + [InlineData(false)] [Theory] - public void PipelineExecution_Logged(bool healthy, bool exception) + public void PipelineExecution_Logged(bool exception) { - var healthString = healthy ? "Healthy" : "Unhealthy"; var context = ResilienceContextPool.Shared.Get("op-key").WithResultType(); var telemetry = Create(); var outcome = exception ? Outcome.FromException(new InvalidOperationException("dummy message")) : Outcome.FromResult((object)10); var result = exception ? "dummy message" : "10"; - if (!healthy) - { - ((List)context.ResilienceEvents).Add(new ResilienceEvent(ResilienceEventSeverity.Warning, "dummy")); - } - ReportEvent(telemetry, outcome: outcome, arg: default(PipelineExecutingArguments), context: context); ReportEvent(telemetry, outcome: outcome, arg: new PipelineExecutedArguments(TimeSpan.FromSeconds(10)), context: context); @@ -373,8 +365,8 @@ public void PipelineExecution_Logged(bool healthy, bool exception) messages[0].Message.Should().Be("Resilience pipeline executing. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key'"); messages = _logger.GetRecords(new EventId(2, "StrategyExecuted")).ToList(); messages.Should().HaveCount(1); - messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '{result}', Execution Health: '{healthString}', Execution Time: 10000ms"); - messages[0].LogLevel.Should().Be(healthy ? LogLevel.Debug : LogLevel.Warning); + messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '{result}', Execution Time: 10000ms"); + messages[0].LogLevel.Should().Be(LogLevel.Debug); } [Fact] @@ -398,28 +390,20 @@ public void PipelineExecution_NoOutcome_Logged() ReportEvent(telemetry, outcome: null, arg: new PipelineExecutedArguments(TimeSpan.FromSeconds(10)), context: context); var messages = _logger.GetRecords(new EventId(2, "StrategyExecuted")).ToList(); - messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '', Execution Health: 'Healthy', Execution Time: 10000ms"); + messages[0].Message.Should().Match($"Resilience pipeline executed. Source: 'my-pipeline/pipeline-instance', Operation Key: 'op-key', Result: '', Execution Time: 10000ms"); } - [InlineData(true, false)] - [InlineData(false, false)] - [InlineData(true, true)] - [InlineData(false, true)] + [InlineData(false)] + [InlineData(true)] [Theory] - public void PipelineExecution_Metered(bool healthy, bool exception) + public void PipelineExecution_Metered(bool exception) { using var metering = TestUtilities.EnablePollyMetering(_events); - var healthString = healthy ? "Healthy" : "Unhealthy"; var context = ResilienceContextPool.Shared.Get("op-key").WithResultType(); var outcome = exception ? Outcome.FromException(new InvalidOperationException("dummy message")) : Outcome.FromResult((object)10); var result = exception ? "dummy message" : "10"; - if (!healthy) - { - ((List)context.ResilienceEvents).Add(new ResilienceEvent(ResilienceEventSeverity.Warning, "dummy")); - } - var telemetry = Create(new[] { new CallbackEnricher(context => @@ -437,7 +421,7 @@ public void PipelineExecution_Metered(bool healthy, bool exception) var ev = _events.Single(v => v.Name == "pipeline-execution-duration").Tags; - ev.Count.Should().Be(exception ? 9 : 8); + ev.Count.Should().Be(exception ? 8 : 7); ev["pipeline-instance"].Should().Be("pipeline-instance"); ev["operation-key"].Should().Be("op-key"); ev["pipeline-name"].Should().Be("my-pipeline"); @@ -454,15 +438,6 @@ public void PipelineExecution_Metered(bool healthy, bool exception) { ev.Should().NotContainKey("exception-name"); } - - if (healthy) - { - ev["execution-health"].Should().Be("Healthy"); - } - else - { - ev["execution-health"].Should().Be("Unhealthy"); - } } [Fact] diff --git a/test/Polly.Extensions.Tests/Utils/ResilienceContextExtensionsTests.cs b/test/Polly.Extensions.Tests/Utils/ResilienceContextExtensionsTests.cs deleted file mode 100644 index e6209416c64..00000000000 --- a/test/Polly.Extensions.Tests/Utils/ResilienceContextExtensionsTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Polly.Telemetry; - -namespace Polly.Extensions.Tests.Utils; - -public class ResilienceContextExtensionsTests -{ - [Fact] - public void IsHealthy_Ok() - { - var context = ResilienceContextPool.Shared.Get(); - AddEvent(context, ResilienceEventSeverity.Warning); - context.IsExecutionHealthy().Should().BeFalse(); - - context = ResilienceContextPool.Shared.Get(); - context.IsExecutionHealthy().Should().BeTrue(); - - context = ResilienceContextPool.Shared.Get(); - AddEvent(context, ResilienceEventSeverity.Information); - context.IsExecutionHealthy().Should().BeTrue(); - - context = ResilienceContextPool.Shared.Get(); - AddEvent(context, ResilienceEventSeverity.Information); - AddEvent(context, ResilienceEventSeverity.Warning); - context.IsExecutionHealthy().Should().BeFalse(); - } - - private static void AddEvent(ResilienceContext context, ResilienceEventSeverity severity) - { - ((List)context.ResilienceEvents).Add(new ResilienceEvent(severity, "dummy")); - } -} diff --git a/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs b/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs index 002793435c8..dd55ea9249b 100644 --- a/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs +++ b/test/Polly.RateLimiting.Tests/OnRateLimiterRejectedArgumentsTests.cs @@ -8,10 +8,9 @@ public class OnRateLimiterRejectedArgumentsTests [Fact] public void Ctor_Ok() { - var args = new OnRateLimiterRejectedArguments(ResilienceContextPool.Shared.Get(), Substitute.For(), TimeSpan.FromSeconds(1)); + var args = new OnRateLimiterRejectedArguments(ResilienceContextPool.Shared.Get(), Substitute.For()); args.Context.Should().NotBeNull(); args.Lease.Should().NotBeNull(); - args.RetryAfter.Should().Be(TimeSpan.FromSeconds(1)); } } diff --git a/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs index e98fd71e6bc..d359555ec44 100644 --- a/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.RateLimiting.Tests/RateLimiterResiliencePipelineBuilderExtensionsTests.cs @@ -173,7 +173,7 @@ private static void AssertRateLimiterStrategy(ResiliencePipelineBuilder builder, { limiterStrategy.OnLeaseRejected.Should().NotBeNull(); limiterStrategy - .OnLeaseRejected!(new OnRateLimiterRejectedArguments(ResilienceContextPool.Shared.Get(), Substitute.For(), null)) + .OnLeaseRejected!(new OnRateLimiterRejectedArguments(ResilienceContextPool.Shared.Get(), Substitute.For())) .Preserve().GetAwaiter().GetResult(); } else diff --git a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs index 2e545df6a53..d9580a03dc9 100644 --- a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs +++ b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs @@ -63,7 +63,6 @@ public async Task Execute_LeaseRejected(bool hasEvents, bool hasRetryAfter) { args.Context.Should().NotBeNull(); args.Lease.Should().Be(_lease); - args.RetryAfter.Should().Be((TimeSpan?)metadata); eventCalled = true; return default; };