From be22d4344d6037ad5104ead6e90419b971e7bff1 Mon Sep 17 00:00:00 2001 From: Martin Tomka Date: Thu, 22 Jun 2023 08:03:26 +0200 Subject: [PATCH 1/2] Adopt Alpha 2 in samples --- Directory.Packages.props | 2 +- samples/DependencyInjection/Program.cs | 6 +- samples/Extensibility/Program.cs | 9 +-- samples/GenericStrategies/Program.cs | 26 ++------- samples/Intro/Program.cs | 15 ++--- samples/Retries/ExecuteHelper.cs | 22 ++++++++ samples/Retries/Program.cs | 77 ++++++++++---------------- 7 files changed, 68 insertions(+), 89 deletions(-) create mode 100644 samples/Retries/ExecuteHelper.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index ee7e1d5f9ed..97f36854f71 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,7 +1,7 @@ true - 8.0.0-alpha.1 + 8.0.0-alpha.2 diff --git a/samples/DependencyInjection/Program.cs b/samples/DependencyInjection/Program.cs index c75982ddf15..9a269514cd8 100644 --- a/samples/DependencyInjection/Program.cs +++ b/samples/DependencyInjection/Program.cs @@ -21,7 +21,7 @@ // You can also register result-based (generic) resilience strategies // First generic parameter is the key type, the second one is the result type // This overload does not use the context argument (simple scenarios) - .AddResilienceStrategy("my-strategy", builder => + .AddResilienceStrategy("my-http-strategy", builder => { builder.AddTimeout(TimeSpan.FromSeconds(1)); }) @@ -35,10 +35,10 @@ ResilienceStrategyProvider strategyProvider = serviceProvider.GetRequiredService>(); // Retrieve the strategy by name -ResilienceStrategy strategy = strategyProvider.Get("my-strategy"); +ResilienceStrategy strategy = strategyProvider.GetStrategy("my-strategy"); // Retrieve the generic strategy by name -ResilienceStrategy genericStrategy = strategyProvider.Get("my-strategy"); +ResilienceStrategy genericStrategy = strategyProvider.GetStrategy("my-http-strategy"); try { diff --git a/samples/Extensibility/Program.cs b/samples/Extensibility/Program.cs index e59e9f006ed..e9edf02b7b0 100644 --- a/samples/Extensibility/Program.cs +++ b/samples/Extensibility/Program.cs @@ -118,18 +118,13 @@ protected override async ValueTask> ExecuteCoreAsync" - public static TBuilder AddMyResilienceStrategy(this TBuilder builder, MyResilienceStrategyOptions options) - where TBuilder : ResilienceStrategyBuilderBase - { - builder.AddStrategy( + public static TBuilder AddMyResilienceStrategy(this TBuilder builder, MyResilienceStrategyOptions options) where TBuilder : ResilienceStrategyBuilderBase + => builder.AddStrategy( // Provide a factory that creates the strategy context => new MyResilienceStrategy(context.Telemetry, options), // Pass the options, note that the options instance is automatically validated by the builder options); - - return builder; - } } diff --git a/samples/GenericStrategies/Program.cs b/samples/GenericStrategies/Program.cs index 08607324620..3904090f42f 100644 --- a/samples/GenericStrategies/Program.cs +++ b/samples/GenericStrategies/Program.cs @@ -14,12 +14,10 @@ ResilienceStrategy strategy = new ResilienceStrategyBuilder() .AddFallback(new FallbackStrategyOptions { - FallbackAction = async _ => + FallbackAction = _ => { - await Task.Delay(10); - // Return fallback result - return new Outcome(new HttpResponseMessage(System.Net.HttpStatusCode.OK)); + return Outcome.FromResultAsTask(new HttpResponseMessage(HttpStatusCode.OK)); }, // You can also use switch expressions for succinct syntax ShouldHandle = outcome => outcome switch @@ -33,22 +31,10 @@ }) .AddRetry(new RetryStrategyOptions { - ShouldRetry = outcome => - { - // We can handle specific result - if (outcome.Result?.StatusCode == HttpStatusCode.InternalServerError) - { - return PredicateResult.True; - } - - // Or exception - if ( outcome.Exception is HttpRequestException) - { - return PredicateResult.True; - } - - return PredicateResult.False; - }, + // You can use "PredicateBuilder" to configure the predicates + ShouldHandle = new PredicateBuilder() + .HandleResult(r => r.StatusCode == HttpStatusCode.InternalServerError) + .Handle(), // Register user callback called whenever retry occurs OnRetry = outcome => { Console.WriteLine($"Retrying '{outcome.Result?.StatusCode}'..."); return default; }, BaseDelay = TimeSpan.FromMilliseconds(400), diff --git a/samples/Intro/Program.cs b/samples/Intro/Program.cs index 4dadeac7b6f..9271bcea4af 100644 --- a/samples/Intro/Program.cs +++ b/samples/Intro/Program.cs @@ -41,16 +41,14 @@ // Add retries using the options .AddRetry(new RetryStrategyOptions { - ShouldRetry = outcome => + // To configure the predicate you can use switch expressions + ShouldHandle = args => args.Exception switch { - // We want to retry on this specific exception - if (outcome.Exception is TimeoutRejectedException) - { - // The "PredicateResult.True" is shorthand to "new ValueTask(true)" - return PredicateResult.True; - } + TimeoutRejectedException => PredicateResult.True, - return PredicateResult.False; + // The "PredicateResult.False" is just shorthand for "new ValueTask(true)" + // You can also use "new PredicateBuilder().Handle()" + _ => PredicateResult.False }, // Register user callback called whenever retry occurs OnRetry = args => { Console.WriteLine($"Retrying...{args.Arguments.Attempt} attempt"); return default; }, @@ -65,7 +63,6 @@ // Register user callback called whenever timeout occurs OnTimeout = args => { - Console.WriteLine($"Timeout occurred after {args.Timeout}!"); return default; } diff --git a/samples/Retries/ExecuteHelper.cs b/samples/Retries/ExecuteHelper.cs new file mode 100644 index 00000000000..9104acb19ba --- /dev/null +++ b/samples/Retries/ExecuteHelper.cs @@ -0,0 +1,22 @@ +using System.Net; + +namespace Retries; + +internal class ExecuteHelper +{ + public bool Fail { get; set; } = true; + + public HttpResponseMessage ExecuteUnstable() + { + if (Fail) + { + Fail = false; + Console.WriteLine($"{DateTime.UtcNow}: Execute failed"); + throw new InvalidOperationException(); + } + + Fail = true; + Console.WriteLine($"{DateTime.UtcNow}: Executed"); + return new HttpResponseMessage(HttpStatusCode.OK); + } +} diff --git a/samples/Retries/Program.cs b/samples/Retries/Program.cs index c567461ae5e..19fa80f7b61 100644 --- a/samples/Retries/Program.cs +++ b/samples/Retries/Program.cs @@ -1,27 +1,22 @@ using Polly; using Polly.Retry; +using Retries; using System.Net; +var helper = new ExecuteHelper(); + // ------------------------------------------------------------------------ -// 1. Create a retry strategy that only handles invalid operation exceptions +// 1. Create a retry strategy that only handles all exceptions // ------------------------------------------------------------------------ ResilienceStrategy strategy = new ResilienceStrategyBuilder() - .AddRetry(new RetryStrategyOptions - { - // Specify what exceptions should be retried - ShouldRetry = outcome => - { - if (outcome.Exception is InvalidOperationException) - { - return PredicateResult.True; - } - - return PredicateResult.False; - }, - }) + // Default retry options handle all exceptions + .AddRetry(new RetryStrategyOptions()) .Build(); +Console.WriteLine("---------------------------------------"); +strategy.Execute(helper.ExecuteUnstable); + // ------------------------------------------------------------------------ // 2. Customize the retry behavior // ------------------------------------------------------------------------ @@ -29,16 +24,8 @@ strategy = new ResilienceStrategyBuilder() .AddRetry(new RetryStrategyOptions { - // Specify what exceptions should be retried - ShouldRetry = outcome => - { - if (outcome.Exception is InvalidOperationException) - { - return PredicateResult.True; - } - - return PredicateResult.False; - }, + // Specify what exceptions should be retried using PredicateBuilder + ShouldHandle = new PredicateBuilder().Handle(), RetryCount = 4, BaseDelay = TimeSpan.FromSeconds(1), @@ -48,6 +35,9 @@ }) .Build(); +Console.WriteLine("---------------------------------------"); +strategy.Execute(helper.ExecuteUnstable); + // ------------------------------------------------------------------------ // 3. Register the callbacks // ------------------------------------------------------------------------ @@ -55,17 +45,12 @@ strategy = new ResilienceStrategyBuilder() .AddRetry(new RetryStrategyOptions { - // Specify what exceptions should be retried - ShouldRetry = outcome => + // Specify what exceptions should be retried using switch expressions + ShouldHandle = args => args.Exception switch { - if (outcome.Exception is InvalidOperationException) - { - return PredicateResult.True; - } - - return PredicateResult.False; + InvalidOperationException => PredicateResult.True, + _ => PredicateResult.False, }, - OnRetry = outcome => { Console.WriteLine($"Retrying attempt {outcome.Arguments.Attempt}..."); @@ -74,6 +59,9 @@ }) .Build(); +Console.WriteLine("---------------------------------------"); +strategy.Execute(helper.ExecuteUnstable); + // ------------------------------------------------------------------------ // 4. Create an HTTP retry strategy that handles both exceptions and results // ------------------------------------------------------------------------ @@ -82,22 +70,10 @@ .AddRetry(new RetryStrategyOptions { // Specify what exceptions or results should be retried - ShouldRetry = outcome => - { - // Now, also handle results - if (outcome.Result?.StatusCode == HttpStatusCode.InternalServerError) - { - return PredicateResult.True; - } - - if (outcome.Exception is InvalidOperationException) - { - return PredicateResult.True; - } - - return PredicateResult.False; - }, - + ShouldHandle = new PredicateBuilder() + .Handle() + .Handle() + .HandleResult(r=>r.StatusCode == HttpStatusCode.InternalServerError), // Specify delay generator RetryDelayGenerator = outcome => { @@ -112,3 +88,6 @@ } }) .Build(); + +Console.WriteLine("---------------------------------------"); +httpStrategy.Execute(helper.ExecuteUnstable); From 873628cbac77c7c2b2b5b51e8611d36e77039414 Mon Sep 17 00:00:00 2001 From: Martin Tomka Date: Thu, 22 Jun 2023 08:05:27 +0200 Subject: [PATCH 2/2] cleanup --- samples/Retries/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Retries/Program.cs b/samples/Retries/Program.cs index 19fa80f7b61..45a0a5eda53 100644 --- a/samples/Retries/Program.cs +++ b/samples/Retries/Program.cs @@ -6,7 +6,7 @@ var helper = new ExecuteHelper(); // ------------------------------------------------------------------------ -// 1. Create a retry strategy that only handles all exceptions +// 1. Create a retry strategy that handles all exceptions // ------------------------------------------------------------------------ ResilienceStrategy strategy = new ResilienceStrategyBuilder()