fix(twincat): review — a connect failure no longer burns the sum-chunk warning; doc precision

- ReadBucketAsync: the once-per-device "sum-read chunk failed" Warning fires only after a successful
  connect; a connect/backoff failure is the connect path's to report. TwinCATSumChunkWarningTests pins
  it (no warning across connect failures, exactly one across two later failing sum polls; red without
  the guard) plus a source guard that ReadGroupAsync builds its SumRead only via CreateSumRead.
- Docs: diagnostics live-gated via the driver harness (/hosts not exercised); TC2 costs 8 reads on the
  first tick and after each reconnect, then <= 4; read counts attributed to the unit tests.

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 21:26:26 -04:00
parent 664ff75ee2
commit a92fb81f00
4 changed files with 118 additions and 9 deletions
@@ -386,9 +386,13 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery
continue;
}
// Set once the connect succeeded: a connect / backoff failure is the connect path's to report (it
// logs its own Warning) and must not consume the once-per-device sum-chunk-failure Warning below.
var connected = false;
try
{
var client = await EnsureConnectedAsync(device, cancellationToken).ConfigureAwait(false);
connected = true;
var items = new TwinCATBulkReadItem[chunk.Count];
for (var k = 0; k < chunk.Count; k++)
items[k] = new TwinCATBulkReadItem(chunk[k].SymbolName, chunk[k].Def.DataType, chunk[k].BitIndex, chunk[k].Def.ArrayLength);
@@ -429,7 +433,7 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery
_health = new DriverHealth(DriverState.Degraded, _health.LastSuccessfulRead, ex.Message);
// Once per device: the health message is overwritten by the next good read in the same poll, so
// without this a sum-read path failing on every poll left no trace (hw2 live gate, 2026-10-08).
if (!device.SumChunkFailureWarned)
if (connected && !device.SumChunkFailureWarned)
{
device.SumChunkFailureWarned = true;
_logger.LogWarning(ex,