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); } } }