using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Hubs; /// /// Singleton last-snapshot-per-instance cache. Populated by /// DriverStatusSignalRBridge as it forwards DPS messages; read by /// so newly-joined clients see current state /// without waiting for the next change event, and subscribed to directly by the Blazor /// Server DriverStatusPanel via . /// public interface IDriverStatusSnapshotStore { /// Stores or replaces the last-known health snapshot for a driver instance. /// The driver health snapshot to store. void Upsert(DriverHealthChanged snapshot); /// Attempts to retrieve the last-known health snapshot for a driver instance. /// The driver instance's stable logical ID. /// The stored snapshot, if found. /// if a snapshot was found; otherwise . bool TryGet(string driverInstanceId, out DriverHealthChanged snapshot); /// Returns a point-in-time snapshot of every driver instance's last-known health. /// A read-only collection of the last-known health snapshot for each driver instance. IReadOnlyCollection GetAll(); /// /// Evicts every snapshot whose driver instance is not in /// and whose last publish is older than . The stores have no other /// removal path, so a deleted (or re-created under a new id) driver would otherwise keep its last /// snapshot until the process restarts. Both conditions are required: the configured set comes from /// the AUTHORED (draft) table, so a driver deleted in /raw but not yet deployed is still /// running and still publishing — it must stay visible until a deploy actually stops it and its /// snapshot goes stale. The /hosts page calls this after each successful config load; a failed /// load must never call it. /// /// The configured driver-instance ids to keep. The set's own /// comparer decides matching. /// Only an unconfigured entry published before this instant is evicted. /// The number of entries removed. int EvictUnconfiguredStale(IReadOnlySet configuredInstanceIds, DateTime olderThanUtc); /// /// Raised after every with the just-stored snapshot. Lets in-process /// consumers (the Blazor Server DriverStatusPanel) receive live updates by reading /// this singleton directly instead of opening a self-targeted SignalR connection — which a /// server-side Blazor component cannot reach when the public URL (e.g. a reverse-proxy port) /// differs from the local Kestrel bind. Handlers run on the caller's thread (the bridge /// actor), so subscribers must marshal to their own sync context. /// event Action? SnapshotChanged; }