diff --git a/bench/Polly.Core.Benchmarks/CreationBenchmark.cs b/bench/Polly.Core.Benchmarks/CreationBenchmark.cs index ac3e507b2bf..52c44f037e2 100644 --- a/bench/Polly.Core.Benchmarks/CreationBenchmark.cs +++ b/bench/Polly.Core.Benchmarks/CreationBenchmark.cs @@ -18,7 +18,7 @@ public static void Fallback_V8() new ResiliencePipelineBuilder() .AddFallback(new() { - FallbackAction = _ => Outcome.FromResultAsTask("fallback") + FallbackAction = _ => Outcome.FromResultAsValueTask("fallback") }) .Build(); } diff --git a/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs b/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs index 77948b2ab05..7fa8cf0ccd5 100644 --- a/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs +++ b/bench/Polly.Core.Benchmarks/PredicateBenchmark.cs @@ -14,11 +14,11 @@ public class PredicateBenchmark { ShouldHandle = args => args.Outcome switch { - { Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True, - { Exception: HttpRequestException } => PredicateResult.True, - { Exception: IOException } => PredicateResult.True, - { Exception: InvalidOperationException } => PredicateResult.False, - _ => PredicateResult.False, + { Result: { StatusCode: HttpStatusCode.InternalServerError } } => PredicateResult.True(), + { Exception: HttpRequestException } => PredicateResult.True(), + { Exception: IOException } => PredicateResult.True(), + { Exception: InvalidOperationException } => PredicateResult.False(), + _ => PredicateResult.False(), } }; diff --git a/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs b/bench/Polly.Core.Benchmarks/ResiliencePipelineBenchmark.cs index 55bea8960cb..54ef684a26a 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.Empty.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false); + await ResiliencePipeline.Empty.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state").ConfigureAwait(false); ResilienceContextPool.Shared.Return(context); } diff --git a/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs b/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs index e4ca157469f..667e8d30b1a 100644 --- a/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs +++ b/bench/Polly.Core.Benchmarks/TelemetryBenchmark.cs @@ -33,7 +33,7 @@ public void Prepare() public async ValueTask Execute() { var context = ResilienceContextPool.Shared.Get(); - await _pipeline!.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state").ConfigureAwait(false); + await _pipeline!.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state").ConfigureAwait(false); ResilienceContextPool.Shared.Return(context); } diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs index c4d2c358d41..c7cd8f451bb 100644 --- a/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs +++ b/bench/Polly.Core.Benchmarks/Utils/Helper.CircuitBreaker.cs @@ -7,7 +7,7 @@ public static object CreateOpenedCircuitBreaker(PollyVersion version, bool handl var manualControl = new CircuitBreakerManualControl(); var options = new CircuitBreakerStrategyOptions { - ShouldHandle = _ => PredicateResult.True, + ShouldHandle = _ => PredicateResult.True(), ManualControl = manualControl, }; @@ -54,9 +54,9 @@ public static object CreateCircuitBreaker(PollyVersion technology) BreakDuration = TimeSpan.FromSeconds(5), ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() } }); }), diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs index 7b5b62aa7c7..856e5a8a7af 100644 --- a/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs +++ b/bench/Polly.Core.Benchmarks/Utils/Helper.Hedging.cs @@ -13,7 +13,7 @@ public static ResiliencePipeline CreateHedging() builder.AddHedging(new HedgingStrategyOptions { ShouldHandle = args => new ValueTask(args.Outcome.Result == Failure), - ActionGenerator = args => () => Outcome.FromResultAsTask("hedged response"), + ActionGenerator = args => () => Outcome.FromResultAsValueTask("hedged response"), }); }); } diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs index 5b15fa917c1..1ff82eaaf8e 100644 --- a/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs +++ b/bench/Polly.Core.Benchmarks/Utils/Helper.MultipleStrategies.cs @@ -29,9 +29,9 @@ internal static partial class Helper Delay = TimeSpan.FromSeconds(1), ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() } }) .AddTimeout(TimeSpan.FromSeconds(1)) @@ -43,9 +43,9 @@ internal static partial class Helper BreakDuration = TimeSpan.FromSeconds(5), ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() } }); @@ -73,9 +73,9 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry Delay = TimeSpan.FromSeconds(1), ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() } }) .AddTimeout(TimeSpan.FromSeconds(1)) @@ -87,9 +87,9 @@ public static ResiliencePipeline CreateNonGenericStrategyPipeline(bool telemetry BreakDuration = TimeSpan.FromSeconds(5), ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() } }); diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs index 4d49ef66825..ae3297d0a31 100644 --- a/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs +++ b/bench/Polly.Core.Benchmarks/Utils/Helper.Retry.cs @@ -23,9 +23,9 @@ public static object CreateRetry(PollyVersion technology) Delay = delay, ShouldHandle = args => args.Outcome switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() }, OnRetry = _ => default }); diff --git a/bench/Polly.Core.Benchmarks/Utils/Helper.cs b/bench/Polly.Core.Benchmarks/Utils/Helper.cs index f0acdc8f243..9fefb506a69 100644 --- a/bench/Polly.Core.Benchmarks/Utils/Helper.cs +++ b/bench/Polly.Core.Benchmarks/Utils/Helper.cs @@ -15,7 +15,7 @@ public static async ValueTask ExecuteAsync(this object obj, PollyVersion version var context = ResilienceContextPool.Shared.Get(); await ((ResiliencePipeline)obj).ExecuteOutcomeAsync( - static (_, _) => Outcome.FromResultAsTask("dummy"), + static (_, _) => Outcome.FromResultAsValueTask("dummy"), context, string.Empty).ConfigureAwait(false); diff --git a/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs b/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs index cc56c1b87aa..fcd35117e06 100644 --- a/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs +++ b/src/Polly.Core/CircuitBreaker/Controller/CircuitStateController.cs @@ -298,9 +298,9 @@ private void SetLastHandledOutcome_NeedsLock(Outcome outcome) { _breakingException = new BrokenCircuitException(BrokenCircuitException.DefaultMessage, exception); } - else if (outcome.TryGetResult(out var result)) + else { - _breakingException = new BrokenCircuitException(BrokenCircuitException.DefaultMessage, result!); + _breakingException = new BrokenCircuitException(BrokenCircuitException.DefaultMessage); } } diff --git a/src/Polly.Core/Outcome.TResult.cs b/src/Polly.Core/Outcome.TResult.cs index 2bb88010b36..ad5a077fce9 100644 --- a/src/Polly.Core/Outcome.TResult.cs +++ b/src/Polly.Core/Outcome.TResult.cs @@ -56,7 +56,7 @@ internal Outcome(ExceptionDispatchInfo exceptionDispatchInfo) /// /// If the operation produced a result, this method does nothing. The thrown exception maintains its original stack trace. /// - public void EnsureSuccess() => ExceptionDispatchInfo?.Throw(); + public void ThrowIfException() => ExceptionDispatchInfo?.Throw(); /// /// Tries to get the result, if available. diff --git a/src/Polly.Core/Outcome.cs b/src/Polly.Core/Outcome.cs index adf0a210fe5..ec6b79e2950 100644 --- a/src/Polly.Core/Outcome.cs +++ b/src/Polly.Core/Outcome.cs @@ -19,7 +19,7 @@ public static class Outcome /// The type of the result. /// The result value. /// A completed that produces . - public static ValueTask> FromResultAsTask(TResult value) => new(FromResult(value)); + public static ValueTask> FromResultAsValueTask(TResult value) => new(FromResult(value)); /// /// Returns a with the given . @@ -42,7 +42,7 @@ public static Outcome FromException(Exception exception) /// The exception. /// A completed that produces . /// Thrown when is . - public static ValueTask> FromExceptionAsTask(Exception exception) + public static ValueTask> FromExceptionAsValueTask(Exception exception) { Guard.NotNull(exception); diff --git a/src/Polly.Core/PredicateResult.cs b/src/Polly.Core/PredicateResult.cs index 89daced9217..49356ac67cb 100644 --- a/src/Polly.Core/PredicateResult.cs +++ b/src/Polly.Core/PredicateResult.cs @@ -6,12 +6,14 @@ namespace Polly; public static class PredicateResult { /// - /// Gets a finished that returns value. + /// Returns a finished that returns value. /// - public static ValueTask True => new(true); + /// A new instance of finished . + public static ValueTask True() => new(true); /// - /// Gets a finished that returns value. + /// Returns a finished that returns value. /// - public static ValueTask False => new(false); + /// A new instance of finished . + public static ValueTask False() => new(false); } diff --git a/src/Polly.Core/PublicAPI.Unshipped.txt b/src/Polly.Core/PublicAPI.Unshipped.txt index d690461ed16..74c19f8c4ed 100644 --- a/src/Polly.Core/PublicAPI.Unshipped.txt +++ b/src/Polly.Core/PublicAPI.Unshipped.txt @@ -15,11 +15,6 @@ Polly.CircuitBreaker.BrokenCircuitException Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException() -> void Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message) -> void Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message, System.Exception! inner) -> void -Polly.CircuitBreaker.BrokenCircuitException -Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message, System.Exception! inner, TResult result) -> void -Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string! message, TResult result) -> void -Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(TResult result) -> void -Polly.CircuitBreaker.BrokenCircuitException.Result.get -> TResult Polly.CircuitBreaker.CircuitBreakerManualControl Polly.CircuitBreaker.CircuitBreakerManualControl.CircuitBreakerManualControl() -> void Polly.CircuitBreaker.CircuitBreakerManualControl.CircuitBreakerManualControl(bool isIsolated) -> void @@ -158,10 +153,10 @@ Polly.HedgingResiliencePipelineBuilderExtensions Polly.LegacySupport Polly.Outcome Polly.Outcome -Polly.Outcome.EnsureSuccess() -> void Polly.Outcome.Exception.get -> System.Exception? Polly.Outcome.Outcome() -> void Polly.Outcome.Result.get -> TResult? +Polly.Outcome.ThrowIfException() -> void Polly.PredicateBuilder Polly.PredicateBuilder.PredicateBuilder() -> void Polly.PredicateBuilder @@ -296,10 +291,9 @@ Polly.Retry.OnRetryArguments.RetryDelay.get -> System.TimeSpan Polly.Retry.RetryDelayGeneratorArguments Polly.Retry.RetryDelayGeneratorArguments.AttemptNumber.get -> int Polly.Retry.RetryDelayGeneratorArguments.Context.get -> Polly.ResilienceContext! -Polly.Retry.RetryDelayGeneratorArguments.DelayHint.get -> System.TimeSpan Polly.Retry.RetryDelayGeneratorArguments.Outcome.get -> Polly.Outcome Polly.Retry.RetryDelayGeneratorArguments.RetryDelayGeneratorArguments() -> void -Polly.Retry.RetryDelayGeneratorArguments.RetryDelayGeneratorArguments(Polly.ResilienceContext! context, Polly.Outcome outcome, int attemptNumber, System.TimeSpan delayHint) -> void +Polly.Retry.RetryDelayGeneratorArguments.RetryDelayGeneratorArguments(Polly.ResilienceContext! context, Polly.Outcome outcome, int attemptNumber) -> void Polly.Retry.RetryPredicateArguments Polly.Retry.RetryPredicateArguments.AttemptNumber.get -> int Polly.Retry.RetryPredicateArguments.Context.get -> Polly.ResilienceContext! @@ -313,7 +307,7 @@ Polly.Retry.RetryStrategyOptions.BackoffType.get -> Polly.DelayBackoffT Polly.Retry.RetryStrategyOptions.BackoffType.set -> void Polly.Retry.RetryStrategyOptions.Delay.get -> System.TimeSpan Polly.Retry.RetryStrategyOptions.Delay.set -> void -Polly.Retry.RetryStrategyOptions.DelayGenerator.get -> System.Func, System.Threading.Tasks.ValueTask>? +Polly.Retry.RetryStrategyOptions.DelayGenerator.get -> System.Func, System.Threading.Tasks.ValueTask>? Polly.Retry.RetryStrategyOptions.DelayGenerator.set -> void Polly.Retry.RetryStrategyOptions.MaxRetryAttempts.get -> int Polly.Retry.RetryStrategyOptions.MaxRetryAttempts.set -> void @@ -403,15 +397,15 @@ static Polly.FallbackResiliencePipelineBuilderExtensions.AddFallback(th static Polly.HedgingResiliencePipelineBuilderExtensions.AddHedging(this Polly.ResiliencePipelineBuilder! builder, Polly.Hedging.HedgingStrategyOptions! options) -> Polly.ResiliencePipelineBuilder! static Polly.LegacySupport.SetProperties(this Polly.ResilienceProperties! resilienceProperties, System.Collections.Generic.IDictionary! properties, out System.Collections.Generic.IDictionary! oldProperties) -> void static Polly.Outcome.FromException(System.Exception! exception) -> Polly.Outcome -static Polly.Outcome.FromExceptionAsTask(System.Exception! exception) -> System.Threading.Tasks.ValueTask> +static Polly.Outcome.FromExceptionAsValueTask(System.Exception! exception) -> System.Threading.Tasks.ValueTask> static Polly.Outcome.FromResult(TResult? value) -> Polly.Outcome -static Polly.Outcome.FromResultAsTask(TResult value) -> System.Threading.Tasks.ValueTask> +static Polly.Outcome.FromResultAsValueTask(TResult value) -> System.Threading.Tasks.ValueTask> static Polly.PredicateBuilder.implicit operator System.Func, System.Threading.Tasks.ValueTask>!(Polly.PredicateBuilder! builder) -> System.Func, System.Threading.Tasks.ValueTask>! static Polly.PredicateBuilder.implicit operator System.Func, System.Threading.Tasks.ValueTask>!(Polly.PredicateBuilder! builder) -> System.Func, System.Threading.Tasks.ValueTask>! static Polly.PredicateBuilder.implicit operator System.Func, System.Threading.Tasks.ValueTask>!(Polly.PredicateBuilder! builder) -> System.Func, System.Threading.Tasks.ValueTask>! static Polly.PredicateBuilder.implicit operator System.Func, System.Threading.Tasks.ValueTask>!(Polly.PredicateBuilder! builder) -> System.Func, System.Threading.Tasks.ValueTask>! -static Polly.PredicateResult.False.get -> System.Threading.Tasks.ValueTask -static Polly.PredicateResult.True.get -> System.Threading.Tasks.ValueTask +static Polly.PredicateResult.False() -> System.Threading.Tasks.ValueTask +static Polly.PredicateResult.True() -> System.Threading.Tasks.ValueTask static Polly.ResilienceContextPool.Shared.get -> Polly.ResilienceContextPool! static Polly.ResiliencePipelineBuilderExtensions.AddPipeline(this TBuilder! builder, Polly.ResiliencePipeline! pipeline) -> TBuilder! static Polly.ResiliencePipelineBuilderExtensions.AddPipeline(this Polly.ResiliencePipelineBuilder! builder, Polly.ResiliencePipeline! pipeline) -> Polly.ResiliencePipelineBuilder! diff --git a/src/Polly.Core/README.md b/src/Polly.Core/README.md index 867d5e2f828..6140cdc6364 100644 --- a/src/Polly.Core/README.md +++ b/src/Polly.Core/README.md @@ -226,10 +226,10 @@ new ResiliencePipelineBuilder() { ShouldRetry = args => args switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: string result } when result == Failure => PredicateResult.True, - { Result: int result } when result == -1 => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: string result } when result == Failure => PredicateResult.True(), + { Result: int result } when result == -1 => PredicateResult.True(), + _ => PredicateResult.False() }, }) .Build(); @@ -243,9 +243,9 @@ new ResiliencePipelineBuilder() { ShouldRetry = args => args switch { - { Exception: InvalidOperationException } => PredicateResult.True, - { Result: result } when result == Failure => PredicateResult.True, - _ => PredicateResult.False + { Exception: InvalidOperationException } => PredicateResult.True(), + { Result: result } when result == Failure => PredicateResult.True(), + _ => PredicateResult.False() }, }) .Build(); diff --git a/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs b/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs index 161c99ad6d9..a327ae6e88d 100644 --- a/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs +++ b/src/Polly.Core/Retry/RetryDelayGeneratorArguments.cs @@ -17,13 +17,11 @@ public readonly struct RetryDelayGeneratorArguments /// The context in which the resilience operation or event occurred. /// The outcome of the resilience operation or event. /// The zero-based attempt number. - /// The delay suggested by the retry strategy. - public RetryDelayGeneratorArguments(ResilienceContext context, Outcome outcome, int attemptNumber, TimeSpan delayHint) + public RetryDelayGeneratorArguments(ResilienceContext context, Outcome outcome, int attemptNumber) { Context = context; Outcome = outcome; AttemptNumber = attemptNumber; - DelayHint = delayHint; } /// @@ -40,9 +38,4 @@ public RetryDelayGeneratorArguments(ResilienceContext context, Outcome /// Gets The zero-based attempt number. /// public int AttemptNumber { get; } - - /// - /// Gets the delay suggested by the retry strategy. - /// - public TimeSpan DelayHint { get; } } diff --git a/src/Polly.Core/Retry/RetryResilienceStrategy.cs b/src/Polly.Core/Retry/RetryResilienceStrategy.cs index 62eccd7e4fa..6d61e7bdaf7 100644 --- a/src/Polly.Core/Retry/RetryResilienceStrategy.cs +++ b/src/Polly.Core/Retry/RetryResilienceStrategy.cs @@ -34,7 +34,7 @@ public RetryResilienceStrategy( public Func, ValueTask> ShouldHandle { get; } - public Func, ValueTask>? DelayGenerator { get; } + public Func, ValueTask>? DelayGenerator { get; } public bool UseJitter { get; } @@ -64,9 +64,9 @@ protected internal override async ValueTask> ExecuteCore(Func var delay = RetryHelper.GetRetryDelay(BackoffType, UseJitter, attempt, BaseDelay, ref retryState, _randomizer); if (DelayGenerator is not null) { - var delayArgs = new RetryDelayGeneratorArguments(context, outcome, attempt, delay); - var newDelay = await DelayGenerator(delayArgs).ConfigureAwait(false); - if (RetryHelper.IsValidDelay(newDelay)) + var delayArgs = new RetryDelayGeneratorArguments(context, outcome, attempt); + + if (await DelayGenerator(delayArgs).ConfigureAwait(false) is TimeSpan newDelay && RetryHelper.IsValidDelay(newDelay)) { delay = newDelay; } diff --git a/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs b/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs index aa4015af4f7..797d65c981b 100644 --- a/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs +++ b/src/Polly.Core/Retry/RetryStrategyOptions.TResult.cs @@ -85,12 +85,13 @@ public class RetryStrategyOptions : ResilienceStrategyOptions /// Gets or sets a generator that calculates the delay between retries. /// /// - /// The generator has precedence over and . + /// The generator can override the delay generated by the retry strategy. If the generator returns , the delay generated + /// by the retry strategy for that attempt will be used. /// /// /// The default value is . /// - public Func, ValueTask>? DelayGenerator { get; set; } + public Func, ValueTask>? DelayGenerator { get; set; } /// /// Gets or sets an event delegate that is raised when the retry happens. diff --git a/src/Polly.Core/Utils/DefaultPredicates.cs b/src/Polly.Core/Utils/DefaultPredicates.cs index ae74ed8cbfd..fdbcb3efa55 100644 --- a/src/Polly.Core/Utils/DefaultPredicates.cs +++ b/src/Polly.Core/Utils/DefaultPredicates.cs @@ -4,8 +4,8 @@ internal static class DefaultPredicates { public static readonly Func> HandleOutcome = args => args.Outcome.Exception switch { - OperationCanceledException => PredicateResult.False, - Exception => PredicateResult.True, - _ => PredicateResult.False + OperationCanceledException => PredicateResult.False(), + Exception => PredicateResult.True(), + _ => PredicateResult.False() }; } diff --git a/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs b/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs index ef2daa09d1d..8ec9515df29 100644 --- a/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs +++ b/src/Polly.Core/Utils/Pipeline/CompositeComponent.cs @@ -97,7 +97,7 @@ private ValueTask> ExecuteCoreWithoutTelemetry { if (context.CancellationToken.IsCancellationRequested) { - return Outcome.FromExceptionAsTask(new OperationCanceledException(context.CancellationToken).TrySetStackTrace()); + return Outcome.FromExceptionAsValueTask(new OperationCanceledException(context.CancellationToken).TrySetStackTrace()); } else { @@ -146,7 +146,7 @@ internal override ValueTask> ExecuteCore( { if (context.CancellationToken.IsCancellationRequested) { - return Outcome.FromExceptionAsTask(new OperationCanceledException(context.CancellationToken).TrySetStackTrace()); + return Outcome.FromExceptionAsValueTask(new OperationCanceledException(context.CancellationToken).TrySetStackTrace()); } return state.Next!.ExecuteCore(state.callback, context, state.state); diff --git a/src/Polly.Core/CircuitBreaker/BrokenCircuitException.TResult.cs b/src/Polly/CircuitBreaker/BrokenCircuitException.TResult.cs similarity index 100% rename from src/Polly.Core/CircuitBreaker/BrokenCircuitException.TResult.cs rename to src/Polly/CircuitBreaker/BrokenCircuitException.TResult.cs diff --git a/src/Polly/Properties/AssemblyInfo.cs b/src/Polly/Properties/AssemblyInfo.cs index a96745bc506..b949813529e 100644 --- a/src/Polly/Properties/AssemblyInfo.cs +++ b/src/Polly/Properties/AssemblyInfo.cs @@ -6,6 +6,5 @@ [assembly: TypeForwardedTo(typeof(ExecutionRejectedException))] [assembly: TypeForwardedTo(typeof(TimeoutRejectedException))] [assembly: TypeForwardedTo(typeof(BrokenCircuitException))] -[assembly: TypeForwardedTo(typeof(BrokenCircuitException<>))] [assembly: TypeForwardedTo(typeof(IsolatedCircuitException))] [assembly: TypeForwardedTo(typeof(CircuitState))] diff --git a/src/Polly/PublicAPI.Shipped.txt b/src/Polly/PublicAPI.Shipped.txt index 4c456056fe9..22ba236f1fa 100644 --- a/src/Polly/PublicAPI.Shipped.txt +++ b/src/Polly/PublicAPI.Shipped.txt @@ -1052,3 +1052,9 @@ static readonly Polly.ExceptionPredicates.None -> Polly.ExceptionPredicates static readonly Polly.ResultPredicates.None -> Polly.ResultPredicates virtual Polly.AsyncPolicy.ImplementationAsync(System.Func action, Polly.Context context, System.Threading.CancellationToken cancellationToken, bool continueOnCapturedContext) -> System.Threading.Tasks.Task virtual Polly.Policy.Implementation(System.Action action, Polly.Context context, System.Threading.CancellationToken cancellationToken) -> void +Polly.CircuitBreaker.BrokenCircuitException +Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string message, System.Exception inner, TResult result) -> void +Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(string message, TResult result) -> void +Polly.CircuitBreaker.BrokenCircuitException.BrokenCircuitException(TResult result) -> void +Polly.CircuitBreaker.BrokenCircuitException.Result.get -> TResult + diff --git a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs index 075e04b55f1..3fb989e7a59 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/BrokenCircuitExceptionTests.cs @@ -12,39 +12,11 @@ public void Ctor_Ok() new BrokenCircuitException("Dummy.", new InvalidOperationException()).InnerException.Should().BeOfType(); } - [Fact] - public void Ctor_Generic_Ok() - { - var exception = new BrokenCircuitException(10); - exception.Result.Should().Be(10); - - exception = new BrokenCircuitException("Dummy.", 10); - exception.Message.Should().Be("Dummy."); - exception.Result.Should().Be(10); - - exception = new BrokenCircuitException("Dummy.", new InvalidOperationException(), 10); - exception.Message.Should().Be("Dummy."); - exception.Result.Should().Be(10); - exception.InnerException.Should().BeOfType(); - } - #if !NETCOREAPP [Fact] public void BinarySerialization_Ok() { BinarySerializationUtil.SerializeAndDeserializeException(new BrokenCircuitException()).Should().NotBeNull(); } - - [Fact] - public void BinarySerialization_Generic_Ok() - { - var result = BinarySerializationUtil - .SerializeAndDeserializeException(new BrokenCircuitException(123)); - - result.Should().NotBeNull(); - - // default - result.Result.Should().Be(0); - } #endif } diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs index d05ebf5914a..c9bb40cb017 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResiliencePipelineBuilderTests.cs @@ -11,7 +11,7 @@ public class CircuitBreakerResiliencePipelineBuilderTests { builder => builder.AddCircuitBreaker(new CircuitBreakerStrategyOptions { - ShouldHandle = _ => PredicateResult.True + ShouldHandle = _ => PredicateResult.True() }), }; @@ -19,7 +19,7 @@ public class CircuitBreakerResiliencePipelineBuilderTests { builder => builder.AddCircuitBreaker(new CircuitBreakerStrategyOptions { - ShouldHandle = _ => PredicateResult.True + ShouldHandle = _ => PredicateResult.True() }), }; @@ -90,12 +90,12 @@ public void AddCircuitBreaker_IntegrationTest() opened.Should().Be(1); halfOpened.Should().Be(0); closed.Should().Be(0); - Assert.Throws>(() => strategy.Execute(_ => 0)); + Assert.Throws(() => strategy.Execute(_ => 0)); // Circuit Half Opened timeProvider.Advance(options.BreakDuration); strategy.Execute(_ => -1); - Assert.Throws>(() => strategy.Execute(_ => 0)); + Assert.Throws(() => strategy.Execute(_ => 0)); opened.Should().Be(2); halfOpened.Should().Be(1); closed.Should().Be(0); diff --git a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs index fe0d54ee9e9..03c7d7c7658 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/CircuitBreakerResilienceStrategyTests.cs @@ -123,7 +123,7 @@ public void Execute_UnhandledException_NoCalls() [Fact] public void Execute_Ok() { - _options.ShouldHandle = _ => PredicateResult.False; + _options.ShouldHandle = _ => PredicateResult.False(); Create().Invoking(s => s.Execute(_ => 0)).Should().NotThrow(); diff --git a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs index 4e846e71385..75bcfc367d5 100644 --- a/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs +++ b/test/Polly.Core.Tests/CircuitBreaker/Controller/CircuitStateControllerTests.cs @@ -118,9 +118,8 @@ public async Task OnActionPreExecute_CircuitOpenedByValue() using var controller = CreateController(); await OpenCircuit(controller, Outcome.FromResult(99)); - var error = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!; - error.Should().BeOfType>(); - error.Result.Should().Be(99); + var error = (BrokenCircuitException)(await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception!; + error.Should().BeOfType(); GetBlockedTill(controller).Should().Be(_timeProvider.GetUtcNow() + _options.BreakDuration); } @@ -219,7 +218,7 @@ public async Task OnActionPreExecute_HalfOpen() // act await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); var error = (await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get())).Value.Exception; - error.Should().BeOfType>(); + error.Should().BeOfType(); // assert controller.CircuitState.Should().Be(CircuitState.HalfOpen); @@ -357,7 +356,7 @@ public async Task OnActionFailureAsync_VoidResult_EnsureBreakingExceptionNotSet( // assert controller.LastException.Should().BeNull(); var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); - outcome.Value.Exception.Should().BeOfType>(); + outcome.Value.Exception.Should().BeOfType(); } [Fact] @@ -392,7 +391,7 @@ public async Task Flow_Closed_HalfOpen_Open_HalfOpen_Closed() // execution rejected AdvanceTime(TimeSpan.FromMilliseconds(1)); var outcome = await controller.OnActionPreExecuteAsync(ResilienceContextPool.Shared.Get()); - outcome.Value.Exception.Should().BeOfType>(); + outcome.Value.Exception.Should().BeOfType(); // wait and try, transition to half open AdvanceTime(_options.BreakDuration + _options.BreakDuration); diff --git a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs index 5c601b34b91..6dbe198712d 100644 --- a/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Fallback/FallbackResiliencePipelineBuilderExtensionsTests.cs @@ -12,8 +12,8 @@ public class FallbackResiliencePipelineBuilderExtensionsTests { builder.AddFallback(new FallbackStrategyOptions { - FallbackAction = _ => Outcome.FromResultAsTask(0), - ShouldHandle = _ => PredicateResult.False, + FallbackAction = _ => Outcome.FromResultAsValueTask(0), + ShouldHandle = _ => PredicateResult.False(), }); } }; diff --git a/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs b/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs index 0e0cbad4ab9..8415d82e19d 100644 --- a/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Fallback/FallbackResilienceStrategyTests.cs @@ -52,7 +52,7 @@ public void ShouldHandle_ArgumentsSetCorrectly(bool handle) args.Outcome.Result.Should().Be("ok"); args.Context.Should().NotBeNull(); called++; - return Outcome.FromResultAsTask("fallback"); + return Outcome.FromResultAsValueTask("fallback"); }); var result = Create().Execute(_ => "ok"); diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs index 33927630462..e31fffc15b1 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingControllerTests.cs @@ -28,7 +28,7 @@ public async Task Pooling_Ok() private static async Task PrepareAsync(HedgingExecutionContext context) { - await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(10), "state"); + await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(10), "state"); await context.TryWaitForCompletedExecutionAsync(System.Threading.Timeout.InfiniteTimeSpan); context.Tasks[0].AcceptOutcome(); } diff --git a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs index bbd20da0eb9..8c0a2700e2d 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/HedgingExecutionContextTests.cs @@ -97,7 +97,7 @@ public async Task TryWaitForCompletedExecutionAsync_FinishedTask_Ok() { var context = Create(); context.Initialize(_resilienceContext); - await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state"); + await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state"); var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero); @@ -182,8 +182,8 @@ public async Task TryWaitForCompletedExecutionAsync_TwiceWhenSecondaryGeneratorN var context = Create(); context.Initialize(_resilienceContext); - await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state"); - await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsTask(new DisposableResult("dummy")), "state"); + await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state"); + await context.LoadExecutionAsync((_, _) => Outcome.FromResultAsValueTask(new DisposableResult("dummy")), "state"); var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero); @@ -199,7 +199,7 @@ public async Task TryWaitForCompletedExecutionAsync_TwiceWhenSecondaryGeneratorR await LoadExecutionAsync(context); await LoadExecutionAsync(context); - Generator = args => () => Outcome.FromResultAsTask(new DisposableResult { Name = "secondary" }); + Generator = args => () => Outcome.FromResultAsValueTask(new DisposableResult { Name = "secondary" }); var task = await context.TryWaitForCompletedExecutionAsync(TimeSpan.Zero); task!.Type.Should().Be(HedgedTaskType.Primary); @@ -470,7 +470,7 @@ private void ConfigureSecondaryTasks(params TimeSpan[] delays) private Func, Func>>?> Generator { get; set; } = args => { - return () => Outcome.FromResultAsTask(new DisposableResult { Name = Handled }); + return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = Handled }); }; private HedgingExecutionContext Create() diff --git a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs index 760831a6b66..fa7ec8280c8 100644 --- a/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs +++ b/test/Polly.Core.Tests/Hedging/Controller/TaskExecutionTests.cs @@ -52,7 +52,7 @@ await execution.InitializeAsync(HedgedTaskType.Primary, _snapshot, { AssertPrimaryContext(context, execution); state.Should().Be("dummy-state"); - return Outcome.FromResultAsTask(new DisposableResult { Name = value }); + return Outcome.FromResultAsValueTask(new DisposableResult { Name = value }); }, "dummy-state", 99); @@ -91,7 +91,7 @@ public async Task Initialize_Secondary_Ok(string value, bool handled) { AssertSecondaryContext(args.ActionContext, execution); args.AttemptNumber.Should().Be(4); - return () => Outcome.FromResultAsTask(new DisposableResult { Name = value }); + return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = value }); }; (await execution.InitializeAsync(HedgedTaskType.Secondary, _snapshot, null!, "dummy-state", 4)).Should().BeTrue(); @@ -255,7 +255,7 @@ private async Task InitializePrimaryAsync(TaskExecution execut await execution.InitializeAsync(HedgedTaskType.Primary, _snapshot, (context, _) => { onContext?.Invoke(context); - return Outcome.FromResultAsTask(result ?? new DisposableResult { Name = Handled }); + return Outcome.FromResultAsValueTask(result ?? new DisposableResult { Name = Handled }); }, "dummy-state", 1); } @@ -296,7 +296,7 @@ private void CreateSnapshot(CancellationToken? token = null) private Func, Func>>?> Generator { get; set; } = args => { - return () => Outcome.FromResultAsTask(new DisposableResult { Name = Handled }); + return () => Outcome.FromResultAsValueTask(new DisposableResult { Name = Handled }); }; private TaskExecution Create() => new(_hedgingHandler, CancellationTokenSourcePool.Create(TimeProvider.System), _timeProvider, _telemetry); diff --git a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs index 0c871989a16..8de0f80fd97 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingActionGeneratorArgumentsTests.cs @@ -7,7 +7,7 @@ public class HedgingActionGeneratorArgumentsTests [Fact] public void Ctor_Ok() { - var args = new HedgingActionGeneratorArguments(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 5, _ => Outcome.FromResultAsTask("dummy")); + var args = new HedgingActionGeneratorArguments(ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 5, _ => Outcome.FromResultAsValueTask("dummy")); args.PrimaryContext.Should().NotBeNull(); args.ActionContext.Should().NotBeNull(); diff --git a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs index 45baab8fdc4..2f988c279b1 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingHandlerTests.cs @@ -9,14 +9,14 @@ public class HedgingHandlerTests public async Task GenerateAction_Generic_Ok() { var handler = new HedgingHandler( - args => PredicateResult.True, - args => () => Outcome.FromResultAsTask("ok")); + args => PredicateResult.True(), + args => () => Outcome.FromResultAsValueTask("ok")); var action = handler.GenerateAction(new HedgingActionGeneratorArguments( ResilienceContextPool.Shared.Get(), ResilienceContextPool.Shared.Get(), 0, - _ => Outcome.FromResultAsTask("primary")))!; + _ => Outcome.FromResultAsValueTask("primary")))!; var res = await action(); res.Result.Should().Be("ok"); diff --git a/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs index bfa2f2b02e5..13e877146f2 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingResiliencePipelineBuilderExtensionsTests.cs @@ -14,8 +14,8 @@ public void AddHedging_Generic_Ok() { _builder.AddHedging(new HedgingStrategyOptions { - ActionGenerator = args => () => Outcome.FromResultAsTask("dummy"), - ShouldHandle = _ => PredicateResult.True + ActionGenerator = args => () => Outcome.FromResultAsValueTask("dummy"), + ShouldHandle = _ => PredicateResult.True() }); _builder.Build().GetPipelineDescriptor().FirstStrategy.StrategyInstance @@ -45,8 +45,8 @@ public async Task AddHedging_IntegrationTest() Delay = TimeSpan.FromMilliseconds(20), ShouldHandle = args => args.Outcome.Result switch { - "error" => PredicateResult.True, - _ => PredicateResult.False + "error" => PredicateResult.True(), + _ => PredicateResult.False() }, ActionGenerator = args => { diff --git a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs index efc80efd2c9..82e757c0738 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingResilienceStrategyTests.cs @@ -65,7 +65,7 @@ public async Task Execute_CancellationRequested_Throws() var context = ResilienceContextPool.Shared.Get(); context.CancellationToken = _cts.Token; - var outcome = await strategy.ExecuteCore((_, _) => Outcome.FromResultAsTask("dummy"), context, "state"); + var outcome = await strategy.ExecuteCore((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state"); outcome.Exception.Should().BeOfType(); outcome.Exception!.StackTrace.Should().Contain("Execute_CancellationRequested_Throws"); } @@ -80,7 +80,7 @@ public void ExecutePrimaryAndSecondary_EnsureAttemptReported() return timeStamp; }; _options.MaxHedgedAttempts = 2; - ConfigureHedging(_ => true, args => () => Outcome.FromResultAsTask("any")); + ConfigureHedging(_ => true, args => () => Outcome.FromResultAsValueTask("any")); var strategy = Create(); strategy.Execute(_ => "dummy"); @@ -101,7 +101,7 @@ public async Task ExecutePrimary_Cancelled_SecondaryShouldBeExecuted() { _options.MaxHedgedAttempts = 2; - ConfigureHedging(o => o.Result == "primary", args => () => Outcome.FromResultAsTask("secondary")); + ConfigureHedging(o => o.Result == "primary", args => () => Outcome.FromResultAsValueTask("secondary")); var strategy = Create(); var result = await strategy.ExecuteAsync( @@ -186,7 +186,7 @@ public async Task ExecuteAsync_EnsurePrimaryContextFlows() { args.PrimaryContext.Properties.GetValue(key, string.Empty).Should().Be("dummy"); args.PrimaryContext.Should().Be(primaryContext); - return () => Outcome.FromResultAsTask(Failure); + return () => Outcome.FromResultAsValueTask(Failure); }); var strategy = Create(); @@ -298,7 +298,7 @@ public async Task ExecuteAsync_EnsureSecondaryHedgedTaskReportedWithNoOutcome() return default; }; - ConfigureHedging(context => Outcome.FromResultAsTask(Success)); + ConfigureHedging(context => Outcome.FromResultAsValueTask(Success)); var strategy = Create(); @@ -326,7 +326,7 @@ public async Task ExecuteAsync_EnsureDiscardedResultDisposed() { return () => { - return Outcome.FromResultAsTask(secondaryResult); + return Outcome.FromResultAsValueTask(secondaryResult); }; }); @@ -530,7 +530,7 @@ public async Task ExecuteAsync_Secondary_CustomPropertiesAvailable() args.ActionContext.Properties.TryGetValue(key2, out var val).Should().BeTrue(); val.Should().Be("my-value-2"); args.ActionContext.Properties.Set(key, "my-value"); - return Outcome.FromResultAsTask(Success); + return Outcome.FromResultAsValueTask(Success); }; }); var strategy = Create(); @@ -549,7 +549,7 @@ public async Task ExecuteAsync_Secondary_CustomPropertiesAvailable() public async Task ExecuteAsync_OnHedgingEventThrows_EnsureExceptionRethrown() { // arrange - ConfigureHedging(args => () => Outcome.FromResultAsTask(Success)); + ConfigureHedging(args => () => Outcome.FromResultAsValueTask(Success)); _options.OnHedging = _ => throw new InvalidOperationException("my-exception"); var strategy = Create(); @@ -651,7 +651,7 @@ ValueTask> BackgroundWork(ResilienceContext resilienceContext) { var delay = Task.Delay(TimeSpan.FromDays(24), resilienceContext.CancellationToken); backgroundTasks.Add(delay); - return Outcome.FromResultAsTask(Success); + return Outcome.FromResultAsValueTask(Success); } } @@ -833,10 +833,10 @@ public async Task ExecuteAsync_ExceptionsHandled_ShouldReturnLastResult() { if (exception != null) { - return Outcome.FromExceptionAsTask(exception); + return Outcome.FromExceptionAsValueTask(exception); } - return Outcome.FromResultAsTask(Success); + return Outcome.FromResultAsValueTask(Success); }; }); @@ -851,7 +851,7 @@ public async Task ExecuteAsync_EnsureHedgingDelayGeneratorRespected() var delay = TimeSpan.FromMilliseconds(12345); _options.DelayGenerator = _ => new ValueTask(TimeSpan.FromMilliseconds(12345)); - ConfigureHedging(res => false, args => () => Outcome.FromResultAsTask(Success)); + ConfigureHedging(res => false, args => () => Outcome.FromResultAsValueTask(Success)); var strategy = Create(); var task = strategy.ExecuteAsync(async token => @@ -892,7 +892,7 @@ public async Task ExecuteAsync_EnsureOnHedgingCalled() return default; }; - ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsTask(Failure)); + ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsValueTask(Failure)); var strategy = Create(); await strategy.ExecuteAsync(_ => new ValueTask(Failure)); @@ -907,7 +907,7 @@ public async Task ExecuteAsync_EnsureOnHedgingTelemetry() { var context = ResilienceContextPool.Shared.Get(); - ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsTask(Failure)); + ConfigureHedging(res => res.Result == Failure, args => () => Outcome.FromResultAsValueTask(Failure)); var strategy = Create(); await strategy.ExecuteAsync((_, _) => new ValueTask(Failure), context, "state"); diff --git a/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs b/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs index 2208428f689..51d02dcd240 100644 --- a/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs +++ b/test/Polly.Core.Tests/Hedging/HedgingStrategyOptionsTests.cs @@ -39,7 +39,7 @@ public async Task HedgingActionGenerator_EnsureDefaults(bool synchronous) Thread.CurrentThread.ManagedThreadId.Should().Be(threadId); } - return Outcome.FromResultAsTask(99); + return Outcome.FromResultAsValueTask(99); }))!; action.Should().NotBeNull(); diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs b/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs index 7b1a829e4db..55e39f54acd 100644 --- a/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs +++ b/test/Polly.Core.Tests/Issues/IssuesTests.FlowingContext_849.cs @@ -18,7 +18,7 @@ public void FlowingContext_849() ResilienceContext context = args.Context; context.Should().NotBeNull(); contextChecked = true; - return PredicateResult.False; + return PredicateResult.False(); } }) .Build(); diff --git a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs index 3065826d2e1..9dfc01af8b2 100644 --- a/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs +++ b/test/Polly.Core.Tests/Issues/IssuesTests.HandleMultipleResults_898.cs @@ -16,11 +16,11 @@ public void HandleMultipleResults_898() ShouldHandle = args => args.Outcome switch { // handle string results - { Result: string res } when res == "error" => PredicateResult.True, + { Result: string res } when res == "error" => PredicateResult.True(), // handle int results - { Result: int res } when res == -1 => PredicateResult.True, - _ => PredicateResult.False + { Result: int res } when res == -1 => PredicateResult.True(), + _ => PredicateResult.False() }, OnRetry = args => { diff --git a/test/Polly.Core.Tests/OutcomeTests.cs b/test/Polly.Core.Tests/OutcomeTests.cs index 4474a652b0a..42e2c1dfc02 100644 --- a/test/Polly.Core.Tests/OutcomeTests.cs +++ b/test/Polly.Core.Tests/OutcomeTests.cs @@ -50,7 +50,7 @@ public void EnsureSuccess_Result() { var outcome = Outcome.FromResult("dummy"); - outcome.Invoking(o => o.EnsureSuccess()).Should().NotThrow(); + outcome.Invoking(o => o.ThrowIfException()).Should().NotThrow(); } [Fact] @@ -58,6 +58,6 @@ public void EnsureSuccess_Exception() { var outcome = Outcome.FromException(new InvalidOperationException()); - outcome.Invoking(o => o.EnsureSuccess()).Should().Throw(); + outcome.Invoking(o => o.ThrowIfException()).Should().Throw(); } } diff --git a/test/Polly.Core.Tests/PredicateResultTests.cs b/test/Polly.Core.Tests/PredicateResultTests.cs index f1a48c0cdca..a3a655fcc8d 100644 --- a/test/Polly.Core.Tests/PredicateResultTests.cs +++ b/test/Polly.Core.Tests/PredicateResultTests.cs @@ -5,12 +5,12 @@ public class PredicateResultTests [Fact] public async Task True_Ok() { - (await PredicateResult.True).Should().BeTrue(); + (await PredicateResult.True()).Should().BeTrue(); } [Fact] public async Task False_Ok() { - (await PredicateResult.False).Should().BeFalse(); + (await PredicateResult.False()).Should().BeFalse(); } } diff --git a/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs b/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs index 4968d635155..ea89af60a89 100644 --- a/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs +++ b/test/Polly.Core.Tests/Registry/ResiliencePipelineRegistryTests.cs @@ -268,7 +268,7 @@ public void EnableReloads_Ok(bool firstOne) builder.AddRetry(new RetryStrategyOptions { - ShouldHandle = _ => PredicateResult.True, + ShouldHandle = _ => PredicateResult.True(), MaxRetryAttempts = retryCount, Delay = TimeSpan.FromMilliseconds(2), }); @@ -344,7 +344,7 @@ public void EnableReloads_Generic_Ok() builder.AddRetry(new RetryStrategyOptions { - ShouldHandle = _ => PredicateResult.True, + ShouldHandle = _ => PredicateResult.True(), MaxRetryAttempts = retryCount, Delay = TimeSpan.FromMilliseconds(2), }); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs index 27dcd6a46b9..333a4d22034 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTTests.Async.cs @@ -87,7 +87,7 @@ public async Task ExecuteOutcomeAsync_GenericStrategy_Ok() state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); context.ResultType.Should().Be(typeof(int)); - return Outcome.FromResultAsTask(12345); + return Outcome.FromResultAsValueTask(12345); }, ResilienceContextPool.Shared.Get(), "state"); diff --git a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs index 1ae26be6741..99bf972b03c 100644 --- a/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs +++ b/test/Polly.Core.Tests/ResiliencePipelineTests.AsyncT.cs @@ -122,7 +122,7 @@ public async Task ExecuteOutcomeAsync_Ok() state.Should().Be("state"); context.IsSynchronous.Should().BeFalse(); context.ResultType.Should().Be(typeof(int)); - return Outcome.FromResultAsTask(12345); + return Outcome.FromResultAsValueTask(12345); }, ResilienceContextPool.Shared.Get(), "state"); diff --git a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs index f02558e023e..5fb9dee6276 100644 --- a/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs +++ b/test/Polly.Core.Tests/Retry/RetryDelayGeneratorArgumentsTests.cs @@ -7,11 +7,10 @@ public class RetryDelayGeneratorArgumentsTests [Fact] public void Ctor_Ok() { - var args = new RetryDelayGeneratorArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2, TimeSpan.FromSeconds(2)); + var args = new RetryDelayGeneratorArguments(ResilienceContextPool.Shared.Get(), Outcome.FromResult(1), 2); args.Context.Should().NotBeNull(); args.Outcome.Result.Should().Be(1); args.AttemptNumber.Should().Be(2); - args.DelayHint.Should().Be(TimeSpan.FromSeconds(2)); } } diff --git a/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs b/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs index 57a0010e371..f73886985ba 100644 --- a/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs +++ b/test/Polly.Core.Tests/Retry/RetryResiliencePipelineBuilderExtensionsTests.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using NSubstitute; using Polly.Retry; using Polly.Testing; @@ -17,7 +18,7 @@ public class RetryResiliencePipelineBuilderExtensionsTests BackoffType = DelayBackoffType.Exponential, MaxRetryAttempts = 3, Delay = TimeSpan.FromSeconds(2), - ShouldHandle = _ => PredicateResult.True, + ShouldHandle = _ => PredicateResult.True(), }); AssertStrategy(builder, DelayBackoffType.Exponential, 3, TimeSpan.FromSeconds(2)); @@ -33,7 +34,7 @@ public class RetryResiliencePipelineBuilderExtensionsTests BackoffType = DelayBackoffType.Exponential, MaxRetryAttempts = 3, Delay = TimeSpan.FromSeconds(2), - ShouldHandle = _ => PredicateResult.True + ShouldHandle = _ => PredicateResult.True() }); AssertStrategy(builder, DelayBackoffType.Exponential, 3, TimeSpan.FromSeconds(2)); @@ -62,7 +63,7 @@ public void AddRetry_GenericOverloads_Ok(Action> public void AddRetry_DefaultOptions_Ok() { var builder = new ResiliencePipelineBuilder(); - var options = new RetryStrategyOptions { ShouldHandle = _ => PredicateResult.True }; + var options = new RetryStrategyOptions { ShouldHandle = _ => PredicateResult.True() }; builder.AddRetry(options); @@ -131,19 +132,18 @@ private static TimeSpan GetAggregatedDelay(RetryStrategyOptions options) { var aggregatedDelay = TimeSpan.Zero; - var strategy = new ResiliencePipelineBuilder().AddRetry(new() + var strategy = new ResiliencePipelineBuilder { TimeProvider = new NoWaitingTimeProvider() }.AddRetry(new() { MaxRetryAttempts = options.MaxRetryAttempts, Delay = options.Delay, BackoffType = options.BackoffType, - ShouldHandle = _ => PredicateResult.True, // always retry until all retries are exhausted - DelayGenerator = args => + ShouldHandle = _ => PredicateResult.True(), // always retry until all retries are exhausted + OnRetry = args => { // the delay hint is calculated for this attempt by the retry strategy - aggregatedDelay += args.DelayHint; + aggregatedDelay += args.RetryDelay; - // return zero delay, so no waiting - return new ValueTask(TimeSpan.Zero); + return default; }, Randomizer = () => 1.0, }) @@ -154,4 +154,13 @@ private static TimeSpan GetAggregatedDelay(RetryStrategyOptions options) return aggregatedDelay; } + + private class NoWaitingTimeProvider : TimeProvider + { + public override ITimer CreateTimer(TimerCallback callback, object? state, TimeSpan dueTime, TimeSpan period) + { + callback(state); + return Substitute.For(); + } + } } diff --git a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs index 4f05e5b3dc6..3e209ffa5cf 100644 --- a/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs +++ b/test/Polly.Core.Tests/Retry/RetryResilienceStrategyTests.cs @@ -40,7 +40,7 @@ public async Task ExecuteAsync_CancellationRequested_EnsureNotRetried() context.CancellationToken = cancellationToken.Token; var executed = false; - var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsTask("dummy"); }, context, "state"); + var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state"); result.Exception.Should().BeOfType(); executed.Should().BeFalse(); } @@ -50,7 +50,7 @@ public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetri { using var cancellationToken = new CancellationTokenSource(); - _options.ShouldHandle = _ => PredicateResult.True; + _options.ShouldHandle = _ => PredicateResult.True(); _options.OnRetry = _ => { cancellationToken.Cancel(); @@ -62,7 +62,7 @@ public async Task ExecuteAsync_CancellationRequestedAfterCallback_EnsureNotRetri context.CancellationToken = cancellationToken.Token; var executed = false; - var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsTask("dummy"); }, context, "state"); + var result = await sut.ExecuteOutcomeAsync((_, _) => { executed = true; return Outcome.FromResultAsValueTask("dummy"); }, context, "state"); result.Exception.Should().BeOfType(); executed.Should().BeTrue(); } @@ -73,7 +73,7 @@ public void ExecuteAsync_MultipleRetries_EnsureDiscardedResultsDisposed() // arrange _options.MaxRetryAttempts = 5; SetupNoDelay(); - _options.ShouldHandle = _ => PredicateResult.True; + _options.ShouldHandle = _ => PredicateResult.True(); var results = new List(); var sut = CreateSut(); @@ -137,7 +137,7 @@ public void RetryDelayGenerator_Respected() var generatedValues = 0; var delay = TimeSpan.FromMilliseconds(120); - _options.ShouldHandle = _ => PredicateResult.True; + _options.ShouldHandle = _ => PredicateResult.True(); _options.MaxRetryAttempts = 3; _options.BackoffType = DelayBackoffType.Constant; @@ -150,7 +150,7 @@ public void RetryDelayGenerator_Respected() _options.DelayGenerator = _ => { generatedValues++; - return new ValueTask(delay); + return new ValueTask(delay); }; CreateSut(TimeProvider.System).Execute(_ => "dummy"); @@ -168,7 +168,7 @@ public async Task RetryDelayGenerator_ZeroDelay_NoTimeProviderCalls() var delay = TimeSpan.Zero; var provider = new ThrowingFakeTimeProvider(); - _options.ShouldHandle = _ => PredicateResult.True; + _options.ShouldHandle = _ => PredicateResult.True(); _options.MaxRetryAttempts = 3; _options.BackoffType = DelayBackoffType.Constant; @@ -180,7 +180,7 @@ public async Task RetryDelayGenerator_ZeroDelay_NoTimeProviderCalls() _options.DelayGenerator = _ => { generatedValues++; - return new ValueTask(delay); + return new ValueTask(delay); }; var sut = CreateSut(provider); @@ -213,7 +213,7 @@ public async void OnRetry_EnsureCorrectArguments() return default; }; - _options.ShouldHandle = args => PredicateResult.True; + _options.ShouldHandle = args => PredicateResult.True(); _options.MaxRetryAttempts = 3; _options.BackoffType = DelayBackoffType.Linear; @@ -243,7 +243,7 @@ public async Task OnRetry_EnsureExecutionTime() return default; }; - _options.ShouldHandle = _ => PredicateResult.True; + _options.ShouldHandle = _ => PredicateResult.True(); _options.MaxRetryAttempts = 1; _options.BackoffType = DelayBackoffType.Constant; _options.Delay = TimeSpan.Zero; @@ -307,12 +307,11 @@ public void RetryDelayGenerator_EnsureCorrectArguments() _options.DelayGenerator = args => { attempts.Add(args.AttemptNumber); - hints.Add(args.DelayHint); args.Outcome.Exception.Should().BeNull(); args.Outcome.Result.Should().Be(0); - return new ValueTask(TimeSpan.Zero); + return new ValueTask(TimeSpan.Zero); }; _options.ShouldHandle = args => args.Outcome.ResultPredicateAsync(0); @@ -327,13 +326,33 @@ public void RetryDelayGenerator_EnsureCorrectArguments() attempts[0].Should().Be(0); attempts[1].Should().Be(1); attempts[2].Should().Be(2); + } + + [Fact] + public void RetryDelayGenerator_ReturnsNull_EnsureDefaultRetry() + { + var delays = new List(); + _options.DelayGenerator = args => new ValueTask((TimeSpan?)null); + _options.OnRetry = args => + { + delays.Add(args.RetryDelay); + return default; + }; + _options.ShouldHandle = args => args.Outcome.ResultPredicateAsync(0); + _options.MaxRetryAttempts = 2; + _options.BackoffType = DelayBackoffType.Constant; + _options.Delay = TimeSpan.FromMilliseconds(2); + + var sut = CreateSut(TimeProvider.System); + + sut.Execute(() => 0); - hints[0].Should().Be(TimeSpan.FromSeconds(2)); - hints[1].Should().Be(TimeSpan.FromSeconds(4)); - hints[2].Should().Be(TimeSpan.FromSeconds(6)); + delays.Should().HaveCount(2); + delays[0].Should().Be(TimeSpan.FromMilliseconds(2)); + delays[1].Should().Be(TimeSpan.FromMilliseconds(2)); } - private void SetupNoDelay() => _options.DelayGenerator = _ => new ValueTask(TimeSpan.Zero); + private void SetupNoDelay() => _options.DelayGenerator = _ => new ValueTask(TimeSpan.Zero); private async ValueTask ExecuteAndAdvance(ResiliencePipeline sut) { diff --git a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs index 324952e67bc..77529774d78 100644 --- a/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs +++ b/test/Polly.Core.Tests/Utils/Pipeline/CompositePipelineComponentTests.cs @@ -50,7 +50,7 @@ public async Task Create_EnsureExceptionsNotWrapped() var pipeline = CreateSut(components); await pipeline - .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsTask(10), ResilienceContextPool.Shared.Get(), "state").AsTask()) + .Invoking(p => p.ExecuteCore((_, _) => Outcome.FromResultAsValueTask(10), ResilienceContextPool.Shared.Get(), "state").AsTask()) .Should() .ThrowAsync(); } @@ -90,7 +90,7 @@ public async Task Create_Cancelled_EnsureNoExecution() var context = ResilienceContextPool.Shared.Get(); context.CancellationToken = cancellation.Token; - var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("result"), context, "state"); + var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("result"), context, "state"); result.Exception.Should().BeOfType(); } @@ -108,7 +108,7 @@ public async Task Create_CancelledLater_EnsureNoExecution() var context = ResilienceContextPool.Shared.Get(); context.CancellationToken = cancellation.Token; - var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("result"), context, "state"); + var result = await pipeline.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("result"), context, "state"); result.Exception.Should().BeOfType(); executed.Should().BeTrue(); } diff --git a/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs b/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs index cf35ede2586..13cae165f7d 100644 --- a/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs +++ b/test/Polly.Extensions.Tests/Issues/IssuesTests.OnCircuitBreakWithServiceProvider_796.cs @@ -33,8 +33,8 @@ public async Task OnCircuitBreakWithServiceProvider_796() }, ShouldHandle = args => args.Outcome.Result switch { - string result when result == "error" => PredicateResult.True, - _ => PredicateResult.False + string result when result == "error" => PredicateResult.True(), + _ => PredicateResult.False() } }); }); diff --git a/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs b/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs index ccf216f19cc..cce6d52d275 100644 --- a/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs +++ b/test/Polly.Extensions.Tests/Issues/IssuesTests.OverrideLibraryStrategies_1072.cs @@ -23,9 +23,9 @@ public void OverrideLibraryStrategies_898(bool overrideStrategy) { ShouldHandle = args => args.Outcome.Exception switch { - InvalidOperationException => PredicateResult.True, - SocketException => PredicateResult.True, - _ => PredicateResult.False + InvalidOperationException => PredicateResult.True(), + SocketException => PredicateResult.True(), + _ => PredicateResult.False() }, Delay = TimeSpan.Zero })); @@ -68,8 +68,8 @@ private static void AddLibraryServices(IServiceCollection services) { ShouldHandle = args => args.Outcome.Exception switch { - InvalidOperationException => PredicateResult.True, - _ => PredicateResult.False + InvalidOperationException => PredicateResult.True(), + _ => PredicateResult.False() } })); } diff --git a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs index e8380d1569e..7972e490734 100644 --- a/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs +++ b/test/Polly.RateLimiting.Tests/RateLimiterResilienceStrategyTests.cs @@ -70,7 +70,7 @@ public async Task Execute_LeaseRejected(bool hasEvents, bool hasRetryAfter) var strategy = Create(); var context = ResilienceContextPool.Shared.Get(cts.Token); - var outcome = await strategy.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsTask("dummy"), context, "state"); + var outcome = await strategy.ExecuteOutcomeAsync((_, _) => Outcome.FromResultAsValueTask("dummy"), context, "state"); outcome.Exception .Should() diff --git a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs index eb5fe71be9e..f213e1f614c 100644 --- a/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs +++ b/test/Polly.Specs/ResiliencePipelineConversionExtensionsTests.cs @@ -152,7 +152,7 @@ public void RetryStrategy_AsSyncPolicy_Ok() var policy = new ResiliencePipelineBuilder() .AddRetry(new RetryStrategyOptions { - ShouldHandle = _ => PredicateResult.True, + ShouldHandle = _ => PredicateResult.True(), BackoffType = DelayBackoffType.Constant, MaxRetryAttempts = 5, Delay = TimeSpan.FromMilliseconds(1) diff --git a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs index 2018ba08824..291329679b4 100644 --- a/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs +++ b/test/Polly.Testing.Tests/ResiliencePipelineExtensionsTests.cs @@ -18,7 +18,7 @@ public void GetPipelineDescriptor_Generic_Ok() var strategy = new ResiliencePipelineBuilder() .AddFallback(new() { - FallbackAction = _ => Outcome.FromResultAsTask("dummy"), + FallbackAction = _ => Outcome.FromResultAsValueTask("dummy"), }) .AddRetry(new()) .AddCircuitBreaker(new())