Files
lmxopcua/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Health/HostConnectivityForwarder.cs
T
Joseph Doherty 64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
docs: backfill XML documentation across 756 files
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
2026-05-28 08:10:17 -04:00

65 lines
3.1 KiB
C#

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Health;
/// <summary>
/// Pushes the synthetic top-level transport-health entry into the
/// <see cref="HostStatusAggregator"/>. Each driver instance has one entry under its
/// <c>MxAccess.ClientName</c> reflecting the gateway transport state — useful for
/// dashboards that want a single "Galaxy is up" signal independent of any individual
/// platform's ScanState.
/// </summary>
/// <remarks>
/// The eventual production source for this signal is the gateway's <c>StreamSessionHealth</c>
/// RPC (mxaccessgw issue gw-6). Until that ships, the driver-side reconnect supervisor
/// (PR 4.5) calls <see cref="SetTransport"/> on transport state transitions:
/// <see cref="HostState.Running"/> when the gw session re-Registers, <see cref="HostState.Stopped"/>
/// when the supervisor moves to <c>TransportLost</c>. The forwarder is intentionally
/// stateless beyond the cached client name + last-pushed value so the supervisor can
/// drive it without any back-pressure plumbing.
/// </remarks>
public sealed class HostConnectivityForwarder : IDisposable
{
private readonly string _clientName;
private readonly HostStatusAggregator _aggregator;
private readonly ILogger _logger;
private bool _disposed;
/// <summary>Initializes a new instance of HostConnectivityForwarder with the given client name, aggregator, and optional logger.</summary>
/// <param name="clientName">The client name for the MxAccess connection.</param>
/// <param name="aggregator">The host status aggregator to push connectivity state to.</param>
/// <param name="logger">The optional logger for diagnostic messages.</param>
public HostConnectivityForwarder(string clientName, HostStatusAggregator aggregator, ILogger? logger = null)
{
ArgumentException.ThrowIfNullOrWhiteSpace(clientName);
_clientName = clientName;
_aggregator = aggregator ?? throw new ArgumentNullException(nameof(aggregator));
_logger = logger ?? NullLogger.Instance;
}
/// <summary>
/// Push a transport state into the aggregator. Idempotent at the aggregator layer —
/// repeated calls with the same state don't fan out duplicate transitions.
/// </summary>
/// <param name="state">The host connectivity state to push.</param>
public void SetTransport(HostState state)
{
ObjectDisposedException.ThrowIf(_disposed, this);
var status = new HostConnectivityStatus(_clientName, state, DateTime.UtcNow);
_aggregator.Update(status);
_logger.LogDebug(
"GalaxyDriver transport state for {ClientName}: {State}",
_clientName, state);
}
/// <summary>Disposes the forwarder and marks it as disposed.</summary>
public void Dispose()
{
// No-op today; reserved for the eventual gw-6 StreamSessionHealth consumer that
// will own a long-running task this method tears down.
_disposed = true;
}
}