refactor(link): bound every teardown and handler wait behind one helper [CI]
This commit is contained in:
1 parent
c05842fd91
commit
d95acc6575
10 files changed
+130
-31
No files matched your search
@@ -0,0 +1,28 @@
|
||||
using Fleet.Core;
|
||||
|
||||
namespace Fleet.Tests;
|
||||
|
||||
public sealed class BoundedTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task WaitAsync_ReturnsFalse_WhenTheWorkNeverFinishes()
|
||||
{
|
||||
var never = new TaskCompletionSource();
|
||||
Assert.False(await Bounded.WaitAsync(never.Task, TimeSpan.FromMilliseconds(100), TimeProvider.System));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WaitAsync_ReturnsTrue_WhenTheWorkFinishes_OrFailsWithSessionNoise()
|
||||
{
|
||||
Assert.True(await Bounded.WaitAsync(Task.CompletedTask, TimeSpan.FromSeconds(5), TimeProvider.System));
|
||||
Assert.True(await Bounded.WaitAsync(Task.FromException(new IOException("closed")), TimeSpan.FromSeconds(5), TimeProvider.System));
|
||||
Assert.True(await Bounded.WaitAsync(Task.FromException(new ObjectDisposedException("x")), TimeSpan.FromSeconds(5), TimeProvider.System));
|
||||
Assert.True(await Bounded.WaitAsync(Task.FromCanceled(new CancellationToken(true)), TimeSpan.FromSeconds(5), TimeProvider.System));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WaitAsync_DoesNotHideRealFailures()
|
||||
{
|
||||
await Assert.ThrowsAsync<FormatException>(() => Bounded.WaitAsync(Task.FromException(new FormatException()), TimeSpan.FromSeconds(5), TimeProvider.System));
|
||||
}
|
||||
}
|
||||
@@ -275,6 +275,27 @@ public sealed class LinkTests
|
||||
await run.WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Session_RunEnds_EvenWhenAnInboundHandlerIsStuck()
|
||||
{
|
||||
(TlsFrameTransport left, TlsFrameTransport right) = await PairAsync();
|
||||
MethodTable table = TestTables.Of(TestTables.Req("right.stuck"));
|
||||
var stuck = new TaskCompletionSource<Result<Number>>(TaskCreationOptions.RunContinuationsAsynchronously); // 不理会取消令牌:模拟卡在原生层的处理器
|
||||
var rightRouter = new RpcRouter<string>(RpcSide.Listener, table).On("right.stuck", LinkJson.Default.Number, LinkJson.Default.Number, (_, _, _) => new ValueTask<Result<Number>>(stuck.Task));
|
||||
await using var leftSession = new RpcSession<string>(left, new RpcRouter<string>(RpcSide.Dialer, table), "left", TimeProvider.System);
|
||||
await using var rightSession = new RpcSession<string>(right, rightRouter, "right", TimeProvider.System);
|
||||
Task leftRun = leftSession.RunAsync(default);
|
||||
Task rightRun = rightSession.RunAsync(default);
|
||||
|
||||
_ = leftSession.RequestAsync("right.stuck", new Number { Value = 1 }, LinkJson.Default.Number, LinkJson.Default.Number, default, TimeSpan.FromSeconds(30)).AsTask();
|
||||
await Task.Delay(300); // 请求到达并进入处理器
|
||||
await leftSession.CloseAsync("bye", default);
|
||||
|
||||
await rightRun.WaitAsync(TimeSpan.FromSeconds(10)); // 以前这里会一直等到处理器返回
|
||||
stuck.TrySetResult(Result<Number>.Ok(new Number { Value = 0 }));
|
||||
await leftRun.WaitAsync(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
|
||||
// ───────────────────────── 点对点握手 ─────────────────────────
|
||||
|
||||
private sealed class PeerFixture : IAsyncDisposable
|
||||
|
||||
Reference in new issue
Block a user