From 3f6b61133eb282c91fa37c70933f734adfd7fc55 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 22 May 2026 10:50:28 -0400 Subject: [PATCH] fix(driver-twincat): resolve Medium code-review finding (Driver.TwinCAT-012) GetMemoryFootprint now returns tagsByName * 256 + nativeSubs * 512 bytes instead of a hard-coded 0; document that the stream-and-discard symbol browse leaves no flushable cache so FlushOptionalCachesAsync is a deliberate no-op. Co-Authored-By: Claude Sonnet 4.6 --- code-reviews/Driver.TwinCAT/findings.md | 2 +- .../TwinCATDriver.cs | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/code-reviews/Driver.TwinCAT/findings.md b/code-reviews/Driver.TwinCAT/findings.md index 0402477..3fc88c3 100644 --- a/code-reviews/Driver.TwinCAT/findings.md +++ b/code-reviews/Driver.TwinCAT/findings.md @@ -325,7 +325,7 @@ re-discovery re-downloads the whole symbol table each time, itself a performance stream-and-discard design is intentional, report the real footprint of `_nativeSubs` / `_tagsByName` and document that the driver holds no flushable cache. -**Resolution:** _(open)_ +**Resolution:** Resolved 2026-05-22 — `GetMemoryFootprint()` now returns `(_tagsByName.Count * 256L) + (_nativeSubs.Count * 512L)`; documented that the driver has no flushable symbol cache (stream-and-discard design) so `FlushOptionalCachesAsync` remains a documented no-op. ### Driver.TwinCAT-013 diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDriver.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDriver.cs index af0400f..9e9e605 100644 --- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDriver.cs +++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/TwinCATDriver.cs @@ -134,7 +134,22 @@ public sealed class TwinCATDriver : IDriver, IReadable, IWritable, ITagDiscovery } public DriverHealth GetHealth() => _health; - public long GetMemoryFootprint() => 0; + + /// + /// Estimated bytes attributable to this driver instance (Driver.TwinCAT-012). + /// This driver holds no flushable symbol cache — BrowseSymbolsAsync streams and + /// discards; the footprint reflects live allocations only: + /// ~256 bytes per pre-declared tag (tag-definition record + dictionary overhead) and + /// ~512 bytes per active native subscription. + /// + public long GetMemoryFootprint() => + (_tagsByName.Count * 256L) + (_nativeSubs.Count * 512L); + + /// + /// No flushable cache exists in this driver — the symbol table is streamed fresh on + /// every call. This is a no-op but is deliberately present + /// so Core's cache-budget enforcement sees a compliant Tier-A driver. + /// public Task FlushOptionalCachesAsync(CancellationToken cancellationToken) => Task.CompletedTask; internal int DeviceCount => _devices.Count;