fix(dcl): stale MxGateway event-loop fault on a cancelled token no longer flaps the fresh connection (plan R2-03 T1)
This commit is contained in:
@@ -105,14 +105,16 @@ public class MxGatewayDataConnection : IDataConnection, IBrowsableDataConnection
|
||||
|
||||
// Background event loop: route each value change to the matching subscription callback.
|
||||
_eventLoopCts = new CancellationTokenSource();
|
||||
_ = Task.Run(() => RunEventLoopAsync(_eventLoopCts.Token));
|
||||
var loopToken = _eventLoopCts.Token; // capture NOW: the field may be replaced by a
|
||||
var loopClient = _client; // subsequent reconnect before Task.Run executes (N1)
|
||||
_ = Task.Run(() => RunEventLoopAsync(loopClient, loopToken));
|
||||
}
|
||||
|
||||
private async Task RunEventLoopAsync(CancellationToken ct)
|
||||
private async Task RunEventLoopAsync(IMxGatewayClient client, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _client!.RunEventLoopAsync(update =>
|
||||
await client.RunEventLoopAsync(update =>
|
||||
{
|
||||
if (_tagToSub.TryGetValue(update.TagPath, out var subId) && _subs.TryGetValue(subId, out var s))
|
||||
s.Callback(update.TagPath, new TagValue(update.Value, update.Quality, update.Timestamp));
|
||||
@@ -122,6 +124,18 @@ public class MxGatewayDataConnection : IDataConnection, IBrowsableDataConnection
|
||||
{
|
||||
// Normal shutdown (DisconnectAsync / DisposeAsync cancelled the loop).
|
||||
}
|
||||
catch (Exception ex) when (ct.IsCancellationRequested)
|
||||
{
|
||||
// Teardown fault of a superseded loop (N1): Cancel() is not synchronous with
|
||||
// the loop's exit — a cancelled/disposed gRPC stream commonly surfaces as
|
||||
// RpcException(StatusCode.Cancelled) (Grpc.Net default without
|
||||
// ThrowOperationCanceledOnCancellation) or ObjectDisposedException from the
|
||||
// concurrent DisposeAsync, milliseconds AFTER ConnectAsync has already reset
|
||||
// _disconnectFired. Any fault on a cancelled token is normal shutdown;
|
||||
// raising Disconnected here would flap the NEW healthy session.
|
||||
_logger.LogDebug(ex,
|
||||
"MxGateway event loop faulted after cancellation — superseded loop teardown; not signalling disconnect");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "MxGateway event stream faulted; signalling disconnect");
|
||||
|
||||
Reference in New Issue
Block a user