fix(drivers): InitializeAsync releases previous device/session state before overwrite (#630)
FOCAS, AbLegacy, AbCip, TwinCAT, S7 and OpcUaClient orphaned the previous probe/recycle/fixed-tree loops and clients when re-initialised on a live driver. Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
@@ -223,6 +223,11 @@ public sealed class S7Driver
|
||||
/// <inheritdoc />
|
||||
public async Task InitializeAsync(string driverConfigJson, CancellationToken cancellationToken)
|
||||
{
|
||||
// #630: InitializeAsync is reachable on a live driver (DriverInstanceActor.AdoptConfigDuringInit
|
||||
// runs it with no teardown first). Stop the previous probe loop and drop the previous connection
|
||||
// before they are overwritten below. Deliberately NOT ShutdownAsync: that also drops _poll and the
|
||||
// subscriptions, which nothing would re-drive.
|
||||
await ReleaseConnectionAsync().ConfigureAwait(false);
|
||||
Health = new DriverHealth(DriverState.Initializing, null, null);
|
||||
try
|
||||
{
|
||||
@@ -360,7 +365,18 @@ public sealed class S7Driver
|
||||
// disposing its CTS (drain-before-dispose, STAB-6-S7), so no poll iteration touches _gate
|
||||
// after this returns.
|
||||
await _poll.DisposeAsync().ConfigureAwait(false);
|
||||
await ReleaseConnectionAsync().ConfigureAwait(false);
|
||||
_writeFault = null;
|
||||
_connectBackoff.RecordSuccess();
|
||||
Health = new DriverHealth(DriverState.Unknown, Health.LastSuccessfulRead, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cancels + bounded-joins the probe loop, then disposes its CTS and the PLC connection. The
|
||||
/// connection part of <see cref="ShutdownAsync"/> (everything but the poll engine and health).
|
||||
/// </summary>
|
||||
private async Task ReleaseConnectionAsync()
|
||||
{
|
||||
var probeCts = _probeCts;
|
||||
var probeTask = _probeTask;
|
||||
try { probeCts?.Cancel(); } catch { }
|
||||
@@ -381,11 +397,8 @@ public sealed class S7Driver
|
||||
|
||||
_initialized = false;
|
||||
_plcDead = false;
|
||||
_writeFault = null;
|
||||
_connectBackoff.RecordSuccess();
|
||||
try { Plc?.Dispose(); } catch { /* best-effort — tearing down anyway */ }
|
||||
Plc = null;
|
||||
Health = new DriverHealth(DriverState.Unknown, Health.LastSuccessfulRead, null);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
Reference in New Issue
Block a user