main
bicijinlian 11 months ago
parent ce5c75a236
commit 625561e22c

@ -1,10 +1,10 @@
namespace Polly8Study.Test namespace Polly8Study.Test
{ {
/// <summary> /// <summary>
/// Polly8超时策略 测试 /// Polly8超时策略 测试
/// 关键: /// 关键:
/// CancellationToken没有这个是不起使用的 /// CancellationToken没有这个是不起使用的
/// 就是之前版本中的乐观超时,悲观超时貌似取消了 /// 就是之前版本中的乐观超时,悲观超时貌似取消了
/// </summary> /// </summary>
public class Polly8RetryStrategyTest public class Polly8RetryStrategyTest
{ {
@ -16,7 +16,7 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 重试策略 /// 重试策略
/// </summary> /// </summary>
[Fact] [Fact]
public void Test() public void Test()

@ -1,10 +1,10 @@
namespace Polly8Study.Test namespace Polly8Study.Test
{ {
/// <summary> /// <summary>
/// Polly8超时策略 测试 /// Polly8超时策略 测试
/// 关键: /// 关键:
/// V8不支持悲观超时 /// V8不支持悲观超时
/// 只支持乐观超时使用内部和外部CancellationToken /// 只支持乐观超时使用内部和外部CancellationToken
/// </summary> /// </summary>
public class Polly8TimeoutStrategyTest public class Polly8TimeoutStrategyTest
{ {
@ -16,29 +16,29 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 超时策略选项 /// 超时策略选项
/// </summary> /// </summary>
[Fact] [Fact]
public void TimeoutStrategyOptions_Test() public void TimeoutStrategyOptions_Test()
{ {
//直接设置 //直接设置
new ResiliencePipelineBuilder() new ResiliencePipelineBuilder()
.AddTimeout(TimeSpan.FromMilliseconds(100)) .AddTimeout(TimeSpan.FromMilliseconds(100))
.Build(); .Build();
//默认值 //默认值
var defaultOption = new TimeoutStrategyOptions(); var defaultOption = new TimeoutStrategyOptions();
//全功能 //全功能
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
{ {
//名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中 //名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中
Name = "timeout", Name = "timeout",
//固定超时时间(启用了TimeoutGenerator则无效) //固定超时时间(启用了TimeoutGenerator则无效)
Timeout = TimeSpan.FromSeconds(2), Timeout = TimeSpan.FromSeconds(2),
//动态超时时间设置 //动态超时时间设置
//TimeoutGenerator = arg => //TimeoutGenerator = arg =>
//{ //{
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1)); // var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
@ -46,7 +46,7 @@ namespace Polly8Study.Test
// return ValueTask.FromResult(ts); // return ValueTask.FromResult(ts);
//}, //},
//发生超时时引发的超时委托 //发生超时时引发的超时委托
OnTimeout = (args) => OnTimeout = (args) =>
{ {
var key = args.Context.OperationKey; var key = args.Context.OperationKey;
@ -55,15 +55,17 @@ namespace Polly8Study.Test
}, },
}; };
//使用 //使用
ResiliencePipeline pipeline = new ResiliencePipelineBuilder() ResiliencePipeline pipeline = new ResiliencePipelineBuilder()
.AddTimeout(timeoutOption) .AddTimeout(timeoutOption)
.Build(); .Build();
Assert.NotEmpty(pipeline.AsSyncPolicy().PolicyKey);
} }
/// <summary> /// <summary>
/// 非可取消任务:忽略超时 /// 非可取消任务:忽略超时
/// 同步执行 /// 同步执行
/// </summary> /// </summary>
[Fact] [Fact]
public void No_CancellationToken_Test() public void No_CancellationToken_Test()
@ -72,24 +74,24 @@ namespace Polly8Study.Test
.AddTimeout(TimeSpan.FromSeconds(1)) .AddTimeout(TimeSpan.FromSeconds(1))
.Build(); .Build();
//外部tcs可省略 //外部tcs可省略
var tcs = new CancellationTokenSource(); var tcs = new CancellationTokenSource();
try try
{ {
pipeline.Execute pipeline.Execute
( (
//此处必须是可取消的任务,否则超时不作为(一直等待) //此处必须是可取消的任务,否则超时不作为(一直等待)
callback: (CancellationToken innerToken) => callback: (CancellationToken innerToken) =>
{ {
//虽然接口耗时大,因为没有使用‘可取消的’ Send请求超时设置被忽略会等待接口正确返回 //虽然接口耗时大,因为没有使用‘可取消的’ Send请求超时设置被忽略会等待接口正确返回
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow"); HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
//关键Send方法 没有传入参数 cancellationToken //关键Send方法 没有传入参数 cancellationToken
//其它同步方法,只要是可取消方法均可 //其它同步方法,只要是可取消方法均可
HttpResponseMessage response = new HttpClient().Send(requestMessage); HttpResponseMessage response = new HttpClient().Send(requestMessage);
if (response.IsSuccessStatusCode == false) if (response.IsSuccessStatusCode == false)
{ {
_output.WriteLine($"非正常响应,响应码:{response.StatusCode}"); _output.WriteLine($"非正常响应,响应码:{response.StatusCode}");
return; return;
} }
var stream = response.Content.ReadAsStream(); var stream = response.Content.ReadAsStream();
@ -98,24 +100,24 @@ namespace Polly8Study.Test
var text = System.Text.UTF8Encoding.UTF8.GetString(bs); var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
_output.WriteLine($"响应内容:{text}"); _output.WriteLine($"响应内容:{text}");
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: tcs.Token cancellationToken: tcs.Token
); );
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {
_output.WriteLine($"任务取消,引发异常:{ex.Message}"); _output.WriteLine($"任务取消,引发异常:{ex.Message}");
} }
catch (TimeoutRejectedException ex) catch (TimeoutRejectedException ex)
{ {
_output.WriteLine($"超时,引发异常:{ex.Message}"); _output.WriteLine($"超时,引发异常:{ex.Message}");
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine($"API服务异常{ex.Message}"); _output.WriteLine($"API服务异常{ex.Message}");
} }
finally finally
{ {
@ -124,21 +126,21 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 可取消任务:超时 /// 可取消任务:超时
/// 同步执行 /// 同步执行
/// </summary> /// </summary>
[Fact] [Fact]
public void Has_CancellationToken_Timeout_Test() public void Has_CancellationToken_Timeout_Test()
{ {
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
{ {
//名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中 //名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中
Name = "timeout", Name = "timeout",
//固定超时时间(启用了TimeoutGenerator则无效) //固定超时时间(启用了TimeoutGenerator则无效)
Timeout = TimeSpan.FromSeconds(1), Timeout = TimeSpan.FromSeconds(1),
//动态超时时间设置 //动态超时时间设置
//TimeoutGenerator = arg => //TimeoutGenerator = arg =>
//{ //{
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1)); // var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
@ -146,10 +148,10 @@ namespace Polly8Study.Test
// return ValueTask.FromResult(ts); // return ValueTask.FromResult(ts);
//}, //},
//发生超时时引发的超时委托 //发生超时时引发的超时委托
OnTimeout = (args) => OnTimeout = (args) =>
{ {
_output.WriteLine("OnTimeout 超时委托执行"); _output.WriteLine("OnTimeout 超时委托执行");
return ValueTask.CompletedTask; return ValueTask.CompletedTask;
}, },
}; };
@ -163,14 +165,14 @@ namespace Polly8Study.Test
{ {
pipeline.Execute pipeline.Execute
( (
//此处必须是可取消的任务,否则超时不作为(一直等待) //此处必须是可取消的任务,否则超时不作为(一直等待)
callback: (innerToken) => callback: (innerToken) =>
{ {
HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow"); HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
var response = new HttpClient().Send(r, innerToken); var response = new HttpClient().Send(r, innerToken);
if (response.IsSuccessStatusCode == false) if (response.IsSuccessStatusCode == false)
{ {
Console.WriteLine("非正常响应"); Console.WriteLine("非正常响应");
return; return;
} }
var stream = response.Content.ReadAsStream(); var stream = response.Content.ReadAsStream();
@ -179,23 +181,23 @@ namespace Polly8Study.Test
var text = System.Text.UTF8Encoding.UTF8.GetString(bs); var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
_output.WriteLine($"响应内容:{text}"); _output.WriteLine($"响应内容:{text}");
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: tcs.Token cancellationToken: tcs.Token
); );
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {
_output.WriteLine($"任务取消,引发异常:{ex.Message}"); _output.WriteLine($"任务取消,引发异常:{ex.Message}");
} }
catch (TimeoutRejectedException ex) catch (TimeoutRejectedException ex)
{ {
_output.WriteLine($"超时,引发异常:{ex.Message}"); _output.WriteLine($"超时,引发异常:{ex.Message}");
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine($"API服务异常{ex.Message}"); _output.WriteLine($"API服务异常{ex.Message}");
} }
finally finally
{ {
@ -204,21 +206,21 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 可取消任务:不超时 /// 可取消任务:不超时
/// 同步执行 /// 同步执行
/// </summary> /// </summary>
[Fact] [Fact]
public void Has_CancellationToken_NotTimeout_Test() public void Has_CancellationToken_NotTimeout_Test()
{ {
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
{ {
//名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中 //名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中
Name = "timeout", Name = "timeout",
//固定超时时间(启用了TimeoutGenerator则无效) //固定超时时间(启用了TimeoutGenerator则无效)
Timeout = TimeSpan.FromSeconds(5), Timeout = TimeSpan.FromSeconds(5),
//动态超时时间设置 //动态超时时间设置
//TimeoutGenerator = arg => //TimeoutGenerator = arg =>
//{ //{
// var ts = TimeSpan.FromSeconds(Math.Pow(2, 1)); // var ts = TimeSpan.FromSeconds(Math.Pow(2, 1));
@ -226,10 +228,10 @@ namespace Polly8Study.Test
// return ValueTask.FromResult(ts); // return ValueTask.FromResult(ts);
//}, //},
//发生超时时引发的超时委托 //发生超时时引发的超时委托
OnTimeout = (args) => OnTimeout = (args) =>
{ {
Console.WriteLine("OnTimeout 超时委托执行"); Console.WriteLine("OnTimeout 超时委托执行");
return ValueTask.CompletedTask; return ValueTask.CompletedTask;
}, },
}; };
@ -243,14 +245,14 @@ namespace Polly8Study.Test
{ {
pipeline.Execute pipeline.Execute
( (
//此处必须是可取消的任务,否则超时不作为(一直等待) //此处必须是可取消的任务,否则超时不作为(一直等待)
callback: (innerToken) => callback: (innerToken) =>
{ {
HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow"); HttpRequestMessage r = new HttpRequestMessage(HttpMethod.Get, "http://localhost:44344/api/Timeout/Slow");
var response = new HttpClient().Send(r, innerToken); var response = new HttpClient().Send(r, innerToken);
if (response.IsSuccessStatusCode == false) if (response.IsSuccessStatusCode == false)
{ {
Console.WriteLine("非正常响应"); Console.WriteLine("非正常响应");
return; return;
} }
var stream = response.Content.ReadAsStream(); var stream = response.Content.ReadAsStream();
@ -259,23 +261,23 @@ namespace Polly8Study.Test
var text = System.Text.UTF8Encoding.UTF8.GetString(bs); var text = System.Text.UTF8Encoding.UTF8.GetString(bs);
_output.WriteLine($"响应内容:{text}"); _output.WriteLine($"响应内容:{text}");
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: tcs.Token cancellationToken: tcs.Token
); );
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {
_output.WriteLine($"任务取消,引发异常:{ex.Message}"); _output.WriteLine($"任务取消,引发异常:{ex.Message}");
} }
catch (TimeoutRejectedException ex) catch (TimeoutRejectedException ex)
{ {
_output.WriteLine($"超时,引发异常:{ex.Message}"); _output.WriteLine($"超时,引发异常:{ex.Message}");
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine($"API服务异常{ex.Message}"); _output.WriteLine($"API服务异常{ex.Message}");
} }
finally finally
{ {
@ -285,25 +287,25 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 不可取消任务:忽略超时 /// 不可取消任务:忽略超时
/// 异步执行 /// 异步执行
/// </summary> /// </summary>
[Fact] [Fact]
public async void No_CancellationToken_ExecuteAsync_Test() public async void No_CancellationToken_ExecuteAsync_Test()
{ {
TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions TimeoutStrategyOptions timeoutOption = new TimeoutStrategyOptions
{ {
//名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中 //名称唯一标识了特定策略的特定实例,也包含在由各个弹性策略生成的遥测数据中
Name = "timeout", Name = "timeout",
//固定超时时间(启用了TimeoutGenerator则无效) //固定超时时间(启用了TimeoutGenerator则无效)
Timeout = TimeSpan.FromSeconds(1), Timeout = TimeSpan.FromSeconds(1),
//发生超时时引发的超时委托 //发生超时时引发的超时委托
OnTimeout = (args) => OnTimeout = (args) =>
{ {
_output.WriteLine("OnTimeout 超时委托执行"); _output.WriteLine("OnTimeout 超时委托执行");
return ValueTask.CompletedTask; return ValueTask.CompletedTask;
}, },
}; };
@ -317,27 +319,27 @@ namespace Polly8Study.Test
{ {
await pipeline.ExecuteAsync await pipeline.ExecuteAsync
( (
//此处为不可取消的任务,忽略超时(会一直等待) //此处为不可取消的任务,忽略超时(会一直等待)
callback: async (innerToken) => callback: async (innerToken) =>
{ {
//完成大约是2秒多而不是超时的1秒多 //完成大约是2秒多而不是超时的1秒多
await Task.Delay (1000*3); await Task.Delay (1000*3);
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: tcs.Token cancellationToken: tcs.Token
); );
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {
_output.WriteLine($"任务取消,引发异常:{ex.Message}"); _output.WriteLine($"任务取消,引发异常:{ex.Message}");
} }
catch (TimeoutRejectedException ex) catch (TimeoutRejectedException ex)
{ {
_output.WriteLine($"超时,引发异常:{ex.Message}"); _output.WriteLine($"超时,引发异常:{ex.Message}");
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine($"API服务异常{ex.Message}"); _output.WriteLine($"API服务异常{ex.Message}");
} }
finally finally
{ {
@ -346,8 +348,8 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 可取消任务:超时 /// 可取消任务:超时
/// 异步执行 /// 异步执行
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[Fact] [Fact]
@ -364,9 +366,9 @@ namespace Polly8Study.Test
( (
callback: async (innerToken) => callback: async (innerToken) =>
{ {
//完成大约是超时的1秒多而不是任务的3秒多 //完成大约是超时的1秒多而不是任务的3秒多
await Task.Delay(1000 * 3, innerToken); await Task.Delay(1000 * 3, innerToken);
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: cts.Token cancellationToken: cts.Token
); );
@ -374,8 +376,8 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 可取消任务:不超时 /// 可取消任务:不超时
/// 异步执行 /// 异步执行
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[Fact] [Fact]
@ -392,9 +394,9 @@ namespace Polly8Study.Test
( (
callback: async (innerToken) => callback: async (innerToken) =>
{ {
//不超时完成大约是任务耗时的1秒 //不超时完成大约是任务耗时的1秒
await Task.Delay(1000, innerToken); await Task.Delay(1000, innerToken);
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
}, },
cancellationToken: cts.Token cancellationToken: cts.Token
); );
@ -406,8 +408,8 @@ namespace Polly8Study.Test
} }
// <summary> // <summary>
/// 可取消任务:超时 /// 可取消任务:超时
/// 异步执行无外层Token /// 异步执行无外层Token
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[Fact] [Fact]
@ -424,9 +426,9 @@ namespace Polly8Study.Test
( (
callback: async (innerToken) => callback: async (innerToken) =>
{ {
//完成大约是超时的1秒多而不是任务的3秒多 //完成大约是超时的1秒多而不是任务的3秒多
await Task.Delay(1000 * 3, innerToken); await Task.Delay(1000 * 3, innerToken);
_output.WriteLine("任务执行完成"); _output.WriteLine("任务执行完成");
} }
); );
}); });
@ -445,22 +447,22 @@ namespace Polly8Study.Test
{ {
pipeline.Execute pipeline.Execute
( (
//此处必须是可取消的任务,否则超时不作为(一直等待) //此处必须是可取消的任务,否则超时不作为(一直等待)
callback: SyncWithCancellationToken, callback: SyncWithCancellationToken,
cancellationToken: tcs.Token cancellationToken: tcs.Token
); );
} }
catch (OperationCanceledException ex) catch (OperationCanceledException ex)
{ {
_output.WriteLine($"任务取消,引发异常:{ex.Message}"); _output.WriteLine($"任务取消,引发异常:{ex.Message}");
} }
catch (TimeoutRejectedException ex) catch (TimeoutRejectedException ex)
{ {
_output.WriteLine($"超时,引发异常:{ex.Message}"); _output.WriteLine($"超时,引发异常:{ex.Message}");
} }
catch (Exception ex) catch (Exception ex)
{ {
_output.WriteLine($"API服务异常{ex.Message}"); _output.WriteLine($"API服务异常{ex.Message}");
} }
finally finally
{ {
@ -469,7 +471,7 @@ namespace Polly8Study.Test
} }
/// <summary> /// <summary>
/// 使用CancellationToken的同步方法 /// 使用CancellationToken的同步方法
/// </summary> /// </summary>
private void SyncWithCancellationToken(CancellationToken cancellationToken) private void SyncWithCancellationToken(CancellationToken cancellationToken)
{ {

@ -1,4 +1,4 @@
namespace Polly8Study.Test namespace Polly8Study.Test
{ {
public class UseXunit public class UseXunit
{ {
@ -12,7 +12,7 @@ namespace Polly8Study.Test
[Fact] [Fact]
public void Use_xUnit_Test() public void Use_xUnit_Test()
{ {
var msg = "使用 xUnit 单元测试框架!"; var msg = "使用 xUnit 单元测试框架!";
Assert.True(true, msg); Assert.True(true, msg);
_output.WriteLine(msg); _output.WriteLine(msg);

@ -1,4 +1,4 @@

using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;

@ -0,0 +1,6 @@
<LUTConfig Version="1.0">
<Repository />
<ParallelBuilds>true</ParallelBuilds>
<ParallelTestRuns>true</ParallelTestRuns>
<TestCaseTimeout>180000</TestCaseTimeout>
</LUTConfig>
Loading…
Cancel
Save