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
@@ -279,6 +279,7 @@ public sealed class FleetLink
|
||||
Task cancellation = Task.Delay(Timeout.Infinite, ct);
|
||||
Task finished = await Task.WhenAny(run, pump, heartbeat, cancellation);
|
||||
string finishedReason = DescribeFinishedTask(finished, run, pump, heartbeat, session.TransportFailure);
|
||||
_session = null; // 链路已经结束:上报方不能再往这条会话上写,收尾卡住时也一样
|
||||
if (ct.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
@@ -295,15 +296,15 @@ public sealed class FleetLink
|
||||
}
|
||||
|
||||
await sessionCts.CancelAsync();
|
||||
await Task.WhenAll(Quiet(run), Quiet(pump), Quiet(heartbeat));
|
||||
await Bounded.WaitAsync(Task.WhenAll(Quiet(run), Quiet(pump), Quiet(heartbeat)), Bounded.Teardown, _time);
|
||||
return finishedReason;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_session = null;
|
||||
await sessionCts.CancelAsync();
|
||||
await Quiet(run);
|
||||
await session.DisposeAsync();
|
||||
await Bounded.WaitAsync(Quiet(run), Bounded.Teardown, _time);
|
||||
await Bounded.WaitAsync(session.DisposeAsync().AsTask(), Bounded.Teardown, _time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ public sealed class WsTransport : IRpcTransport
|
||||
public sealed class TlsFrameTransport : IRpcTransport
|
||||
{
|
||||
private const int HeaderBytes = 5;
|
||||
private static readonly TimeSpan s_sendTimeout = TimeSpan.FromSeconds(20);
|
||||
|
||||
private readonly Stream _stream;
|
||||
private readonly int _maxFrameBytes;
|
||||
@@ -139,16 +140,29 @@ public sealed class TlsFrameTransport : IRpcTransport
|
||||
byte[] header = new byte[HeaderBytes];
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(header, (uint)frame.Data.Length);
|
||||
header[4] = (byte)frame.Kind;
|
||||
await _sendLock.WaitAsync(ct);
|
||||
// 对端黑洞时写会一直挂着并占着发送锁,心跳、时钟同步和重连都跟着卡住:超时就掐掉这条连接
|
||||
using var timeout = new CancellationTokenSource(s_sendTimeout);
|
||||
using CancellationTokenSource linked = CancellationTokenSource.CreateLinkedTokenSource(ct, timeout.Token);
|
||||
bool lockTaken = false;
|
||||
try
|
||||
{
|
||||
await _stream.WriteAsync(header, ct);
|
||||
await _stream.WriteAsync(frame.Data, ct);
|
||||
await _stream.FlushAsync(ct);
|
||||
await _sendLock.WaitAsync(linked.Token);
|
||||
lockTaken = true;
|
||||
await _stream.WriteAsync(header, linked.Token);
|
||||
await _stream.WriteAsync(frame.Data, linked.Token);
|
||||
await _stream.FlushAsync(linked.Token);
|
||||
}
|
||||
catch (OperationCanceledException) when (timeout.IsCancellationRequested && !ct.IsCancellationRequested)
|
||||
{
|
||||
await _stream.DisposeAsync();
|
||||
throw new TimeoutException($"peer send timed out after {s_sendTimeout.TotalSeconds:0} seconds");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_sendLock.Release();
|
||||
if (lockTaken)
|
||||
{
|
||||
_sendLock.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user