using Microsoft.Extensions.Logging; namespace ZB.MOM.WW.ScadaBridge.DeploymentManager; /// /// Default implementation. A simple /// in-process event broadcaster: registered as a DI singleton so it is shared /// between the central-process and the Central /// UI's Blazor circuits (CentralUI-006). /// /// A throwing subscriber must never break the deployment pipeline, so each /// handler is invoked individually and its exceptions are caught and logged. /// public sealed class DeploymentStatusNotifier : IDeploymentStatusNotifier { private readonly ILogger _logger; /// Initializes a new instance of . /// Logger instance used when a subscriber throws. public DeploymentStatusNotifier(ILogger logger) { _logger = logger; } /// public event Action? StatusChanged; /// public void NotifyStatusChanged(DeploymentStatusChange change) { var handlers = StatusChanged; if (handlers == null) return; // Invoke each subscriber in isolation: one faulting handler (e.g. a // disposed Blazor circuit) must not stop the others from being notified // and must not propagate back into the deployment pipeline. foreach (var handler in handlers.GetInvocationList()) { try { ((Action)handler)(change); } catch (Exception ex) { _logger.LogWarning(ex, "A deployment-status-change subscriber threw for deployment {DeploymentId} " + "(status {Status}); continuing with remaining subscribers", change.DeploymentId, change.Status); } } } }