using System.Collections.Concurrent; using ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers; namespace ZB.MOM.WW.OtOpcUa.AdminUI.Hubs; /// /// Thread-safe in-memory implementation of . /// Keyed by (DriverInstanceId, HostName); last write wins. /// public sealed class InMemoryDriverResilienceStatusStore : IDriverResilienceStatusStore { private readonly ConcurrentDictionary<(string Instance, string Host), DriverResilienceStatusChanged> _byPair = new(); /// public event Action? SnapshotChanged; /// public void Upsert(DriverResilienceStatusChanged snapshot) { _byPair[(snapshot.DriverInstanceId, snapshot.HostName)] = snapshot; // Capture-then-invoke so a concurrent unsubscribe can't null the delegate mid-raise. SnapshotChanged?.Invoke(snapshot); } /// public IReadOnlyList GetForInstance(string driverInstanceId) => _byPair.Values .Where(s => string.Equals(s.DriverInstanceId, driverInstanceId, StringComparison.Ordinal)) .ToList(); /// public IReadOnlyCollection GetAll() => _byPair.Values.ToArray(); }