You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
7.1 KiB
C#

2 months ago
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<int> optionsOnFallback = new FallbackStrategyOptions<int>
{
ShouldHandle = new PredicateBuilder<int>()
.Handle<Exception>()
.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<TResult> instance to the pipeline
var pipeline = new ResiliencePipelineBuilder<int>()
.AddFallback(optionsOnFallback)
.Build();
var data = await pipeline.ExecuteAsync<int>(static async (innerToken) =>
{
return await Task.FromResult(Random.Shared.Next(1, 100));
});
_output.WriteLine(data.ToString());
}
/// <summary>
/// 生成回退选项
/// 注意:一定是有返回值的,否则没意义
/// </summary>
[Fact]
public async Task Create_FallbackStrategyOption_TestAsync()
{
//以返回简单的字符串或数据为例
// 1、操作失败(异常或返回值不满足),则回退为固定值
var optionsSubstitute = new FallbackStrategyOptions<string>
{
//设置回退条件
ShouldHandle = new PredicateBuilder<string>()
//出现指定的异常类型时,回退
.Handle<Exception>()
//返回值满足条件时,回退
.HandleResult(r => r is null),
//回退时,返回的替代值
FallbackAction = static args => Outcome.FromResultAsValueTask("回退时的值")
};
// 2、如果操作失败则回退为动态生成值
var optionsFallbackAction = new FallbackStrategyOptions<string>
{
//设置回退条件
ShouldHandle = new PredicateBuilder<string>()
//出现指定的异常类型时,回退
.Handle<Exception>()
//返回值满足条件时,回退
.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<string>
{
ShouldHandle = new PredicateBuilder<string>()
//出现指定的异常类型时,回退
.Handle<Exception>()
//返回值满足条件时,回退
.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<string>()
.AddFallback(optionsOnFallback)
.Build();
//使用弹性管道,执行/调用 方法
var data = await pipeline.ExecuteAsync<string>(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);
}
/// <summary>
/// 生成回退选项
/// 注意:一定是有返回值的,否则没意义
/// </summary>
[Fact]
public async Task FallbackStrategyOption_TestAsync()
{
//方法返回 1-00 随机数使用回退方法确保返回0-50的数据。
var optionsOnFallback = new FallbackStrategyOptions<int>
{
ShouldHandle = new PredicateBuilder<int>()
.Handle<Exception>()
.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<TResult> instance to the pipeline
var pipeline = new ResiliencePipelineBuilder<int>()
.AddFallback(optionsOnFallback)
.Build();
var data = await pipeline.ExecuteAsync<int>(async (innerToken) =>
{
//随机返回1到100数字
var v = Random.Shared.Next(1, 100);
_output.WriteLine($"方法生成数字为:{v}");
return await Task.FromResult(v);
});
Assert.True(data <= 50);
}
}
}