diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md index bcf0047a751..bce12dcf602 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerBenchmark-report-github.md @@ -9,7 +9,7 @@ Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 LaunchCount=2 WarmupCount=10 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|------------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:| -| ExecuteCircuitBreaker_V7 | 310.9 ns | 2.48 ns | 3.48 ns | 1.00 | 0.00 | 0.0200 | 504 B | 1.00 | -| ExecuteCircuitBreaker_V8 | 545.0 ns | 2.72 ns | 3.99 ns | 1.75 | 0.02 | 0.0010 | 32 B | 0.06 | +| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | +|------------------------- |---------:|--------:|--------:|------:|-------:|----------:|------------:| +| ExecuteCircuitBreaker_V7 | 309.0 ns | 3.53 ns | 5.18 ns | 1.00 | 0.0200 | 504 B | 1.00 | +| ExecuteCircuitBreaker_V8 | 369.5 ns | 3.27 ns | 4.68 ns | 1.19 | 0.0010 | 32 B | 0.06 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerOpenedBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerOpenedBenchmark-report-github.md index fe8a2b7520a..50dd8748ad7 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerOpenedBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.CircuitBreakerOpenedBenchmark-report-github.md @@ -11,6 +11,6 @@ LaunchCount=2 WarmupCount=10 ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | |-------------------------- |------------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| -| ExecuteAsync_Exception_V7 | 30,264.7 ns | 282.61 ns | 386.83 ns | 53.54 | 0.93 | 0.0916 | 2888 B | 12.89 | -| ExecuteAsync_Exception_V8 | 20,805.9 ns | 123.75 ns | 169.39 ns | 36.81 | 0.76 | 0.0610 | 1848 B | 8.25 | -| ExecuteAsync_Outcome_V8 | 565.4 ns | 7.41 ns | 10.15 ns | 1.00 | 0.00 | 0.0086 | 224 B | 1.00 | +| ExecuteAsync_Exception_V7 | 30,077.7 ns | 130.12 ns | 190.73 ns | 51.40 | 0.53 | 0.0610 | 2888 B | 12.89 | +| ExecuteAsync_Exception_V8 | 20,036.3 ns | 52.50 ns | 75.30 ns | 34.24 | 0.29 | 0.0610 | 1848 B | 8.25 | +| ExecuteAsync_Outcome_V8 | 585.3 ns | 3.50 ns | 4.91 ns | 1.00 | 0.00 | 0.0086 | 224 B | 1.00 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md index d540bba3abd..975bc7755d2 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.GenericOverheadBenchmark-report-github.md @@ -9,7 +9,7 @@ Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 LaunchCount=2 WarmupCount=10 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | -|------------------------ |---------:|---------:|---------:|------:|--------:|----------:|------------:| -| ExecuteAsync_Generic | 29.98 ns | 0.110 ns | 0.158 ns | 1.00 | 0.00 | - | NA | -| ExecuteAsync_NonGeneric | 33.06 ns | 0.282 ns | 0.404 ns | 1.10 | 0.02 | - | NA | +| Method | Mean | Error | StdDev | Ratio | Allocated | Alloc Ratio | +|------------------------ |---------:|---------:|---------:|------:|----------:|------------:| +| ExecuteAsync_Generic | 29.91 ns | 0.117 ns | 0.168 ns | 1.00 | - | NA | +| ExecuteAsync_NonGeneric | 32.02 ns | 0.084 ns | 0.121 ns | 1.07 | - | NA | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md index 22680d90283..93573b501c1 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.HedgingBenchmark-report-github.md @@ -11,7 +11,7 @@ LaunchCount=2 WarmupCount=10 ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Gen1 | Allocated | Alloc Ratio | |---------------------------- |---------:|----------:|----------:|------:|--------:|-------:|-------:|----------:|------------:| -| Hedging_Primary | 1.087 μs | 0.0101 μs | 0.0141 μs | 1.00 | 0.00 | 0.0019 | - | 80 B | 1.00 | -| Hedging_Secondary | 1.910 μs | 0.0180 μs | 0.0269 μs | 1.76 | 0.04 | 0.0095 | - | 280 B | 3.50 | -| Hedging_Primary_AsyncWork | 5.156 μs | 0.1238 μs | 0.1814 μs | 4.74 | 0.15 | 0.0534 | 0.0229 | 1435 B | 17.94 | -| Hedging_Secondary_AsyncWork | 7.947 μs | 0.2024 μs | 0.2966 μs | 7.33 | 0.34 | 0.0763 | 0.0381 | 1951 B | 24.39 | +| Hedging_Primary | 1.209 μs | 0.0074 μs | 0.0110 μs | 1.00 | 0.00 | 0.0019 | - | 80 B | 1.00 | +| Hedging_Secondary | 2.152 μs | 0.0666 μs | 0.0933 μs | 1.78 | 0.08 | 0.0076 | - | 280 B | 3.50 | +| Hedging_Primary_AsyncWork | 5.962 μs | 0.5393 μs | 0.7560 μs | 4.93 | 0.64 | 0.0534 | 0.0229 | 1443 B | 18.04 | +| Hedging_Secondary_AsyncWork | 9.242 μs | 1.0615 μs | 1.5889 μs | 7.64 | 1.32 | 0.0610 | 0.0458 | 1815 B | 22.69 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md index 6be412d7071..cef5a8ef22f 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.MultipleStrategiesBenchmark-report-github.md @@ -9,7 +9,7 @@ Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 LaunchCount=2 WarmupCount=10 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|--------------------------- |---------:|----------:|----------:|------:|--------:|-------:|----------:|------------:| -| ExecuteStrategyPipeline_V7 | 2.291 μs | 0.0265 μs | 0.0388 μs | 1.00 | 0.00 | 0.1106 | 2824 B | 1.00 | -| ExecuteStrategyPipeline_V8 | 2.053 μs | 0.0118 μs | 0.0177 μs | 0.90 | 0.02 | 0.0038 | 136 B | 0.05 | +| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | +|--------------------------- |---------:|----------:|----------:|------:|-------:|----------:|------------:| +| ExecuteStrategyPipeline_V7 | 2.294 μs | 0.0055 μs | 0.0080 μs | 1.00 | 0.1106 | 2824 B | 1.00 | +| ExecuteStrategyPipeline_V8 | 1.743 μs | 0.0139 μs | 0.0208 μs | 0.76 | 0.0019 | 72 B | 0.03 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md index 20129f40fc4..72e1aa82aee 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.PipelineBenchmark-report-github.md @@ -9,16 +9,16 @@ Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 LaunchCount=2 WarmupCount=10 ``` -| Method | Components | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|------------------- |----------- |-----------:|---------:|---------:|------:|--------:|-------:|----------:|------------:| -| **ExecutePipeline_V7** | **1** | **104.6 ns** | **0.96 ns** | **1.41 ns** | **1.00** | **0.00** | **0.0120** | **304 B** | **1.00** | -| ExecutePipeline_V8 | 1 | 179.6 ns | 2.04 ns | 2.86 ns | 1.72 | 0.04 | - | - | 0.00 | -| | | | | | | | | | | -| **ExecutePipeline_V7** | **2** | **267.0 ns** | **0.83 ns** | **1.22 ns** | **1.00** | **0.00** | **0.0219** | **552 B** | **1.00** | -| ExecutePipeline_V8 | 2 | 236.3 ns | 1.11 ns | 1.63 ns | 0.89 | 0.01 | - | - | 0.00 | -| | | | | | | | | | | -| **ExecutePipeline_V7** | **5** | **901.0 ns** | **4.79 ns** | **7.02 ns** | **1.00** | **0.00** | **0.0515** | **1296 B** | **1.00** | -| ExecutePipeline_V8 | 5 | 456.0 ns | 4.72 ns | 6.76 ns | 0.51 | 0.01 | - | - | 0.00 | -| | | | | | | | | | | -| **ExecutePipeline_V7** | **10** | **1,942.6 ns** | **35.76 ns** | **50.14 ns** | **1.00** | **0.00** | **0.0992** | **2536 B** | **1.00** | -| ExecutePipeline_V8 | 10 | 699.6 ns | 3.93 ns | 5.63 ns | 0.36 | 0.01 | - | - | 0.00 | +| Method | Components | Mean | Error | StdDev | Median | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | +|------------------- |----------- |------------:|----------:|----------:|------------:|------:|--------:|-------:|----------:|------------:| +| **ExecutePipeline_V7** | **1** | **110.61 ns** | **4.817 ns** | **7.060 ns** | **107.53 ns** | **1.00** | **0.00** | **0.0120** | **304 B** | **1.00** | +| ExecutePipeline_V8 | 1 | 68.63 ns | 0.583 ns | 0.778 ns | 68.32 ns | 0.62 | 0.04 | - | - | 0.00 | +| | | | | | | | | | | | +| **ExecutePipeline_V7** | **2** | **267.80 ns** | **3.493 ns** | **5.228 ns** | **269.12 ns** | **1.00** | **0.00** | **0.0219** | **552 B** | **1.00** | +| ExecutePipeline_V8 | 2 | 118.35 ns | 5.882 ns | 8.246 ns | 124.97 ns | 0.44 | 0.04 | - | - | 0.00 | +| | | | | | | | | | | | +| **ExecutePipeline_V7** | **5** | **880.79 ns** | **9.145 ns** | **13.405 ns** | **877.94 ns** | **1.00** | **0.00** | **0.0515** | **1296 B** | **1.00** | +| ExecutePipeline_V8 | 5 | 255.76 ns | 1.435 ns | 2.149 ns | 255.36 ns | 0.29 | 0.00 | - | - | 0.00 | +| | | | | | | | | | | | +| **ExecutePipeline_V7** | **10** | **1,882.96 ns** | **15.883 ns** | **23.773 ns** | **1,885.28 ns** | **1.00** | **0.00** | **0.0992** | **2536 B** | **1.00** | +| ExecutePipeline_V8 | 10 | 524.46 ns | 1.388 ns | 2.034 ns | 524.45 ns | 0.28 | 0.00 | - | - | 0.00 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md index 2c5a7c4c9cb..3de9eb98965 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RateLimiterBenchmark-report-github.md @@ -11,5 +11,5 @@ LaunchCount=2 WarmupCount=10 ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | |---------------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:| -| ExecuteRateLimiter_V7 | 229.4 ns | 1.23 ns | 1.72 ns | 1.00 | 0.00 | 0.0148 | 376 B | 1.00 | -| ExecuteRateLimiter_V8 | 342.4 ns | 2.90 ns | 4.26 ns | 1.49 | 0.02 | 0.0014 | 40 B | 0.11 | +| ExecuteRateLimiter_V7 | 237.2 ns | 2.86 ns | 4.19 ns | 1.00 | 0.00 | 0.0148 | 376 B | 1.00 | +| ExecuteRateLimiter_V8 | 235.8 ns | 0.76 ns | 1.06 ns | 0.99 | 0.02 | 0.0014 | 40 B | 0.11 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md index e65c25e569f..0ae4d0b074f 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.ResilienceStrategyBenchmark-report-github.md @@ -11,7 +11,7 @@ LaunchCount=2 WarmupCount=10 ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Allocated | Alloc Ratio | |----------------------------------------------- |----------:|---------:|---------:|------:|--------:|----------:|------------:| -| ExecuteOutcomeAsync | 61.80 ns | 0.537 ns | 0.770 ns | 1.00 | 0.00 | - | NA | -| ExecuteAsync_ResilienceContextAndState | 169.88 ns | 1.252 ns | 1.755 ns | 2.75 | 0.05 | - | NA | -| ExecuteAsync_CancellationToken | 178.11 ns | 0.894 ns | 1.253 ns | 2.88 | 0.02 | - | NA | -| ExecuteAsync_GenericStrategy_CancellationToken | 181.22 ns | 0.512 ns | 0.701 ns | 2.93 | 0.04 | - | NA | +| ExecuteOutcomeAsync | 69.47 ns | 0.660 ns | 0.947 ns | 1.00 | 0.00 | - | NA | +| ExecuteAsync_ResilienceContextAndState | 179.56 ns | 4.533 ns | 6.500 ns | 2.59 | 0.12 | - | NA | +| ExecuteAsync_CancellationToken | 190.38 ns | 3.343 ns | 4.900 ns | 2.74 | 0.08 | - | NA | +| ExecuteAsync_GenericStrategy_CancellationToken | 182.27 ns | 1.452 ns | 2.083 ns | 2.62 | 0.05 | - | NA | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md index 06e1b4731d7..89f6b1a71bc 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.RetryBenchmark-report-github.md @@ -11,5 +11,5 @@ LaunchCount=2 WarmupCount=10 ``` | Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | |---------------- |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:| -| ExecuteRetry_V7 | 236.4 ns | 1.83 ns | 2.68 ns | 1.00 | 0.00 | 0.0219 | 552 B | 1.00 | -| ExecuteRetry_V8 | 283.2 ns | 0.95 ns | 1.39 ns | 1.20 | 0.02 | - | - | 0.00 | +| ExecuteRetry_V7 | 246.9 ns | 2.25 ns | 3.36 ns | 1.00 | 0.00 | 0.0219 | 552 B | 1.00 | +| ExecuteRetry_V8 | 172.9 ns | 4.08 ns | 5.85 ns | 0.70 | 0.03 | - | - | 0.00 | diff --git a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md index 2d63daad1eb..74c593ec7f8 100644 --- a/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md +++ b/BenchmarkDotNet.Artifacts/results/Polly.Core.Benchmarks.TimeoutBenchmark-report-github.md @@ -9,7 +9,7 @@ Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15 LaunchCount=2 WarmupCount=10 ``` -| Method | Mean | Error | StdDev | Ratio | RatioSD | Gen0 | Allocated | Alloc Ratio | -|------------------ |---------:|--------:|--------:|------:|--------:|-------:|----------:|------------:| -| ExecuteTimeout_V7 | 383.2 ns | 2.10 ns | 2.94 ns | 1.00 | 0.00 | 0.0286 | 728 B | 1.00 | -| ExecuteTimeout_V8 | 415.4 ns | 4.12 ns | 5.50 ns | 1.08 | 0.02 | 0.0010 | 32 B | 0.04 | +| Method | Mean | Error | StdDev | Ratio | Gen0 | Allocated | Alloc Ratio | +|------------------ |---------:|--------:|--------:|------:|-------:|----------:|------------:| +| ExecuteTimeout_V7 | 381.1 ns | 2.96 ns | 4.42 ns | 1.00 | 0.0286 | 728 B | 1.00 | +| ExecuteTimeout_V8 | 262.6 ns | 1.96 ns | 2.88 ns | 0.69 | - | - | 0.00 | diff --git a/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs b/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs index 6632c848324..086560d6b3e 100644 --- a/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs +++ b/src/Polly.Core.Benchmarks/ResilienceStrategyBenchmark.cs @@ -6,16 +6,15 @@ namespace Polly.Core.Benchmarks; +#pragma warning disable CA1822 // Mark members as static + public class ResilienceStrategyBenchmark { - private readonly DummyResilienceStrategy _strategy = new(); - private readonly ResilienceStrategy _genericStrategy = NullResilienceStrategy.Instance; - [Benchmark(Baseline = true)] public async ValueTask ExecuteOutcomeAsync() { var context = ResilienceContext.Get(); - await _strategy.ExecuteOutcomeAsync((_, _) => new ValueTask>(new Outcome("dummy")), context, "state").ConfigureAwait(false); + await NullResilienceStrategy.Instance.ExecuteOutcomeAsync((_, _) => new ValueTask>(new Outcome("dummy")), context, "state").ConfigureAwait(false); ResilienceContext.Return(context); } @@ -23,33 +22,20 @@ public async ValueTask ExecuteOutcomeAsync() public async ValueTask ExecuteAsync_ResilienceContextAndState() { var context = ResilienceContext.Get(); - await _strategy.ExecuteAsync((_, _) => new ValueTask("dummy"), context, "state").ConfigureAwait(false); + await NullResilienceStrategy.Instance.ExecuteAsync((_, _) => new ValueTask("dummy"), context, "state").ConfigureAwait(false); ResilienceContext.Return(context); } [Benchmark] public async ValueTask ExecuteAsync_CancellationToken() { - await _strategy.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); + await NullResilienceStrategy.Instance.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); } [Benchmark] public async ValueTask ExecuteAsync_GenericStrategy_CancellationToken() { - await _genericStrategy.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); - } - - private class DummyResilienceStrategy : ResilienceStrategy - { - public ValueTask> ExecuteOutcomeAsync( - Func>> callback, - ResilienceContext context, - TState state) => ExecuteCoreAsync(callback, context, state); - - protected override ValueTask> ExecuteCoreAsync( - Func>> callback, - ResilienceContext context, - TState state) => callback(context, state); + await NullResilienceStrategy.Instance.ExecuteAsync(_ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); } public class NonGenericStrategy diff --git a/src/Polly.Core.Benchmarks/Utils/Helper.cs b/src/Polly.Core.Benchmarks/Utils/Helper.cs index 965dedbd0e7..c05306f1d52 100644 --- a/src/Polly.Core.Benchmarks/Utils/Helper.cs +++ b/src/Polly.Core.Benchmarks/Utils/Helper.cs @@ -1,5 +1,7 @@ #pragma warning disable S4225 // Extension methods should not extend "object" +using Polly.Strategy; + namespace Polly.Core.Benchmarks.Utils; internal static partial class Helper @@ -12,7 +14,14 @@ public static async ValueTask ExecuteAsync(this object obj, PollyVersion version await ((IAsyncPolicy)obj).ExecuteAsync(static _ => Task.FromResult("dummy"), CancellationToken.None).ConfigureAwait(false); return; case PollyVersion.V8: - await ((ResilienceStrategy)obj).ExecuteAsync(static _ => new ValueTask("dummy"), CancellationToken.None).ConfigureAwait(false); + var context = ResilienceContext.Get(); + + await ((ResilienceStrategy)obj).ExecuteOutcomeAsync( + static (_, _) => new ValueTask>(new Outcome("dummy")), + context, + string.Empty).ConfigureAwait(false); + + ResilienceContext.Return(context); return; } diff --git a/src/Polly.Core.Tests/ResilienceStrategyTests.Async.ValueTaskT.cs b/src/Polly.Core.Tests/ResilienceStrategyTests.Async.ValueTaskT.cs index 7f0eefe1bcb..64817f1c188 100644 --- a/src/Polly.Core.Tests/ResilienceStrategyTests.Async.ValueTaskT.cs +++ b/src/Polly.Core.Tests/ResilienceStrategyTests.Async.ValueTaskT.cs @@ -1,3 +1,5 @@ +using Polly.Strategy; + namespace Polly.Core.Tests; #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously @@ -113,4 +115,20 @@ static async ValueTask AssertStackTrace(Func MyThrowingMethod() => throw new FormatException(); } + + [Fact] + public async Task ExecuteOutcomeAsync_Ok() + { + var result = await NullResilienceStrategy.Instance.ExecuteOutcomeAsync((context, state) => + { + state.Should().Be("state"); + context.IsSynchronous.Should().BeFalse(); + context.ResultType.Should().Be(typeof(int)); + return new Outcome(12345).AsValueTask(); + }, + ResilienceContext.Get(), + "state"); + + result.Result.Should().Be(12345); + } } diff --git a/src/Polly.Core.Tests/ResilienceStrategyTests.TResult.Async.cs b/src/Polly.Core.Tests/ResilienceStrategyTests.TResult.Async.cs index 778f15d4960..0b0abf86092 100644 --- a/src/Polly.Core.Tests/ResilienceStrategyTests.TResult.Async.cs +++ b/src/Polly.Core.Tests/ResilienceStrategyTests.TResult.Async.cs @@ -1,3 +1,4 @@ +using Polly.Strategy; using Xunit; namespace Polly.Core.Tests; @@ -77,4 +78,20 @@ public async Task ExecuteAsync_GenericStrategy_Ok(Func.Instance.ExecuteOutcomeAsync((context, state) => + { + state.Should().Be("state"); + context.IsSynchronous.Should().BeFalse(); + context.ResultType.Should().Be(typeof(int)); + return new Outcome(12345).AsValueTask(); + }, + ResilienceContext.Get(), + "state"); + + result.Result.Should().Be(12345); + } } diff --git a/src/Polly.Core/ResilienceStrategy.Async.ValueTaskT.cs b/src/Polly.Core/ResilienceStrategy.Async.ValueTaskT.cs index 4e695e546e5..b1550efec73 100644 --- a/src/Polly.Core/ResilienceStrategy.Async.ValueTaskT.cs +++ b/src/Polly.Core/ResilienceStrategy.Async.ValueTaskT.cs @@ -7,6 +7,33 @@ namespace Polly; public abstract partial class ResilienceStrategy { + /// + /// Executes the specified outcome-based callback. + /// + /// The type of result returned by the callback. + /// The type of state associated with the callback. + /// The user-provided callback. + /// The context associated with the callback. + /// The state associated with the callback. + /// The instance of that represents the asynchronous execution. + /// Thrown when or is . + /// + /// This method is for advanced and high performance scenarios. The caller must make sure that the + /// does not throw any exceptions. Instead, it converts them to . + /// + public ValueTask> ExecuteOutcomeAsync( + Func>> callback, + ResilienceContext context, + TState state) + { + Guard.NotNull(callback); + Guard.NotNull(context); + + InitializeAsyncContext(context); + + return ExecuteCoreAsync(callback, context, state); + } + /// /// Executes the specified callback. /// diff --git a/src/Polly.Core/ResilienceStrategy.TResult.Async.cs b/src/Polly.Core/ResilienceStrategy.TResult.Async.cs index 6ecde5d10dd..2ed739fd4a4 100644 --- a/src/Polly.Core/ResilienceStrategy.TResult.Async.cs +++ b/src/Polly.Core/ResilienceStrategy.TResult.Async.cs @@ -1,3 +1,5 @@ +using Polly.Strategy; + namespace Polly; /// @@ -85,4 +87,28 @@ public ValueTask ExecuteAsync( return Strategy.ExecuteAsync(callback, cancellationToken); } + + /// + /// Executes the specified outcome-based callback. + /// + /// The type of state associated with the callback. + /// The user-provided callback. + /// The context associated with the callback. + /// The state associated with the callback. + /// The instance of that represents the asynchronous execution. + /// Thrown when or is . + /// + /// This method is for advanced and high performance scenarios. The caller must make sure that the + /// does not throw any exceptions. Instead, it converts them to . + /// + public ValueTask> ExecuteOutcomeAsync( + Func>> callback, + ResilienceContext context, + TState state) + { + Guard.NotNull(callback); + Guard.NotNull(context); + + return Strategy.ExecuteOutcomeAsync(callback, context, state); + } } diff --git a/src/Polly.Core/Timeout/TimeoutResilienceStrategy.cs b/src/Polly.Core/Timeout/TimeoutResilienceStrategy.cs index f58c33660c2..d6907154529 100644 --- a/src/Polly.Core/Timeout/TimeoutResilienceStrategy.cs +++ b/src/Polly.Core/Timeout/TimeoutResilienceStrategy.cs @@ -44,11 +44,8 @@ protected internal override async ValueTask> ExecuteCoreAsync GetTimeoutAsync(ResilienceContext context) return TimeoutGenerator(new TimeoutGeneratorArguments(context)); } - private static CancellationTokenRegistration CreateRegistration(CancellationTokenSource cancellationSource, CancellationToken previousToken) + private static CancellationTokenRegistration? CreateRegistration(CancellationTokenSource cancellationSource, CancellationToken previousToken) { if (previousToken.CanBeCanceled) { return previousToken.Register(static state => ((CancellationTokenSource)state!).Cancel(), cancellationSource, useSynchronizationContext: false); } - return default; + return null; } }