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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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