diff --git a/Polly8Study.Test/Polly8FallbackStrategy.cs b/Polly8Study.Test/Polly8FallbackStrategy.cs deleted file mode 100644 index d4a8866..0000000 --- a/Polly8Study.Test/Polly8FallbackStrategy.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Polly8Study.Test -{ - class Polly8FallbackStrategy - { - } -} diff --git a/Polly8Study.Test/Polly8FallbackStrategyTest.cs b/Polly8Study.Test/Polly8FallbackStrategyTest.cs new file mode 100644 index 0000000..3e0368a --- /dev/null +++ b/Polly8Study.Test/Polly8FallbackStrategyTest.cs @@ -0,0 +1,201 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Polly8Study.Test +{ + public class Polly8FallbackStrategyTest + { + private readonly ITestOutputHelper _output; + + public Polly8FallbackStrategyTest(ITestOutputHelper testOutput) + { + _output = testOutput; + } + + [Fact] + public async void Test() + { + FallbackStrategyOptions optionsOnFallback = new FallbackStrategyOptions + { + ShouldHandle = new PredicateBuilder() + .Handle() + .HandleResult(r => r > 50), + + FallbackAction = static args => + { + var v = Random.Shared.Next(1, 50); + return Outcome.FromResultAsValueTask(v); + }, + + OnFallback = args => + { + _output.WriteLine(args.Outcome.Result.ToString()); + // Add extra logic to be executed when the fallback is triggered, such as logging. + return default; // Returns an empty ValueTask + } + }; + + // Add a fallback strategy with a FallbackStrategyOptions instance to the pipeline + var pipeline = new ResiliencePipelineBuilder() + .AddFallback(optionsOnFallback) + .Build(); + + var data = await pipeline.ExecuteAsync(static async (innerToken) => + { + + return await Task.FromResult(Random.Shared.Next(1, 100)); + + }); + + _output.WriteLine(data.ToString()); + + } + + /// + /// 生成回退选项 + /// 注意:一定是有返回值的,否则没意义 + /// + [Fact] + public async Task Create_FallbackStrategyOption_TestAsync() + { + //以返回简单的字符串或数据为例 + + // 1、操作失败(异常或返回值不满足),则回退为固定值 + var optionsSubstitute = new FallbackStrategyOptions + { + //设置回退条件 + ShouldHandle = new PredicateBuilder() + //出现指定的异常类型时,回退 + .Handle() + //返回值满足条件时,回退 + .HandleResult(r => r is null), + + //回退时,返回的替代值 + FallbackAction = static args => Outcome.FromResultAsValueTask("回退时的值") + }; + + // 2、如果操作失败,则回退为动态生成值 + var optionsFallbackAction = new FallbackStrategyOptions + { + //设置回退条件 + ShouldHandle = new PredicateBuilder() + //出现指定的异常类型时,回退 + .Handle() + //返回值满足条件时,回退 + .HandleResult(r => r is null), + + FallbackAction = static args => + { + var text = Random.Shared.Next(100, 999).ToString(); + return Outcome.FromResultAsValueTask(text); + } + }; + + // 3、使用默认值或动态生成的值,如果触发回退,则执行其他操作。 + var optionsOnFallback = new FallbackStrategyOptions + { + ShouldHandle = new PredicateBuilder() + //出现指定的异常类型时,回退 + .Handle() + //返回值满足条件时,回退 + .HandleResult(r => r is null), + + //回退时:返回替代值 + FallbackAction = static args => + { + var text = Random.Shared.Next(100, 999).ToString(); + return Outcome.FromResultAsValueTask(text); + }, + + //回退时:执行额外方法 + OnFallback = static args => + { + //从参数里可以拿到上下文和结果 + Console.WriteLine(args.Outcome.Result); + + // 添加在触发回退时要执行的额外逻辑,例如日志记录。 + return default; // Returns an empty ValueTask + } + }; + + // 添加到弹性管道 + var pipeline = new ResiliencePipelineBuilder() + .AddFallback(optionsOnFallback) + .Build(); + + //使用弹性管道,执行/调用 方法 + var data = await pipeline.ExecuteAsync(static async (innerToken) => + { + var data = Random.Shared.Next(1,100); + + if (data % 0 ==0) + { + throw new Exception(""); + } + + return await ValueTask.FromResult(data.ToString()); + }); + + //断言 + Assert.NotEmpty(data); + } + + /// + /// 生成回退选项 + /// 注意:一定是有返回值的,否则没意义 + /// + [Fact] + public async Task FallbackStrategyOption_TestAsync() + { + //方法返回 1-00 随机数,使用回退方法确保返回0-50的数据。 + + var optionsOnFallback = new FallbackStrategyOptions + { + ShouldHandle = new PredicateBuilder() + .Handle() + .HandleResult(r => r >= 50), + + //回退时:返回替代值 + FallbackAction = args => + { + var v = Random.Shared.Next(1, 50); + + _output.WriteLine($"原方法生成的数字 {args.Outcome.Result},大于50,使用回退替代值 {v}"); + + return Outcome.FromResultAsValueTask(v); + }, + + //回退时:执行额外方法(先于FallbackAction执行) + OnFallback = args => + { + //从参数里可以拿到上下文和结果 + _output.WriteLine($"回退额外方法执行,原方法生成数字为:{args.Outcome.Result}"); + + // 添加在触发回退时要执行的额外逻辑,例如日志记录。 + return default; // Returns an empty ValueTask + } + }; + + // Add a fallback strategy with a FallbackStrategyOptions instance to the pipeline + var pipeline = new ResiliencePipelineBuilder() + .AddFallback(optionsOnFallback) + .Build(); + + var data = await pipeline.ExecuteAsync(async (innerToken) => + { + //随机返回1到100数字 + var v = Random.Shared.Next(1, 100); + _output.WriteLine($"方法生成数字为:{v}"); + + return await Task.FromResult(v); + + }); + + Assert.True(data <= 50); + } + + } +}