826312befe
Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns, normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping the rationale they annotated. Comment-only: comment-stripped sources are identical to the parent commit.
89 lines
5.8 KiB
C#
89 lines
5.8 KiB
C#
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Commons.Messages.Drivers;
|
|
|
|
/// <summary>
|
|
/// Snapshot of a single driver instance's health, published to the
|
|
/// <c>driver-health</c> DistributedPubSub topic whenever a driver actor
|
|
/// transitions state or logs an error. Consumed by
|
|
/// <c>DriverStatusSignalRBridge</c> in the AdminUI for live status push.
|
|
/// </summary>
|
|
/// <param name="ClusterId">Cluster this driver belongs to.</param>
|
|
/// <param name="DriverInstanceId">Globally-unique driver instance ID.</param>
|
|
/// <param name="State">DriverState enum as string (Healthy, Faulted, Reconnecting, etc.).</param>
|
|
/// <param name="LastSuccessfulReadUtc">Most recent successful equipment read; null if never.</param>
|
|
/// <param name="LastError">Latest error message; null when none.</param>
|
|
/// <param name="ErrorCount5Min">Number of state-transitions into Faulted in the last 5 minutes.</param>
|
|
/// <param name="PublishedUtc">Timestamp this snapshot was published.</param>
|
|
/// <param name="RediscoveryNeededUtc">
|
|
/// When the driver last raised <c>IRediscoverable.OnRediscoveryNeeded</c> — i.e. it observed that the
|
|
/// remote's tag set may have changed (a Galaxy redeploy, a TwinCAT symbol-version bump, an MTConnect
|
|
/// agent restart, a Sparkplug rebirth). Null when the driver has never raised it, or does not
|
|
/// implement <c>IRediscoverable</c>.
|
|
/// <para><b>Advisory only.</b> The served address space is NOT rebuilt in response — raw tags are
|
|
/// authored explicitly through the <c>/raw</c> browse-commit flow. This is a prompt for an operator
|
|
/// to re-browse the device and commit whatever changed.</para>
|
|
/// </param>
|
|
/// <param name="RediscoveryReason">
|
|
/// The driver-supplied reason string from the same event (e.g. <c>"deploy-time-changed"</c>), shown
|
|
/// to the operator alongside the prompt. Null when <paramref name="RediscoveryNeededUtc"/> is null.
|
|
/// </param>
|
|
/// <param name="HostStatuses">
|
|
/// Per-host connectivity as reported by <c>IHostConnectivityProbe.GetHostStatuses()</c>, or null when
|
|
/// the driver does not implement that capability. Empty (not null) when it does but knows no hosts yet.
|
|
/// <para><b>Why this rides the health snapshot rather than a table.</b> The <c>DriverHostStatus</c>
|
|
/// entity used to own this, with a doc-comment describing a publisher hosted service that upserted rows
|
|
/// from each driver node. That publisher was never built, and since per-cluster mesh Phase 4 it is
|
|
/// unbuildable as described: <c>Program.cs</c> gates <c>AddOtOpcUaConfigDb</c> on the <c>admin</c> role,
|
|
/// so a driver-only node has no ConfigDb connection to write rows to. This channel already reaches
|
|
/// <c>/hosts</c>, already survives the mesh split via the Phase 5 gRPC telemetry stream, and already
|
|
/// replays a last-value snapshot on every (re)subscribe — so per-host state re-primes after a
|
|
/// reconnect without a durable store. The table was dropped.</para>
|
|
/// <para><b>Value-equality caveat.</b> A record's generated <c>Equals</c> compares this list by
|
|
/// REFERENCE, so two <c>DriverHealthChanged</c> carrying equal-but-distinct lists are not equal.
|
|
/// Nothing dedups on record equality — <c>DriverInstanceActor</c> keeps its own flattened fingerprint
|
|
/// precisely because of this — but do not introduce such a comparison without fixing it here first.</para>
|
|
/// </param>
|
|
/// <param name="SkippedTags">
|
|
/// What this driver skipped when it last built its tag table, from
|
|
/// <c>ISkippedTagReporter.GetSkippedTags()</c>; null when the driver does not implement that
|
|
/// capability. All twelve production drivers do.
|
|
/// <para><b>Why this is on the health snapshot.</b> A skip happens at init, is not an
|
|
/// error, and does not stop the driver's OTHER tags from reading — so <c>State</c> stays Healthy,
|
|
/// <c>ErrorCount5Min</c> stays 0, <c>LastError</c> stays null and <c>LastSuccessfulReadUtc</c> keeps
|
|
/// advancing while the driver ignores part or all of its configuration. On the Makino
|
|
/// that combination held while 20 of 22 tags were ignored. This field is what contradicts it.</para>
|
|
/// <para><b>Additive, never a state change.</b> See <c>ISkippedTagReporter</c> for why a skipped tag
|
|
/// must not latch the driver non-Healthy — it would satisfy both halves of the comms-loss
|
|
/// conjunction and reconnect-loop a healthy device.</para>
|
|
/// <para><b>Value-equality caveat</b> — the same one <paramref name="HostStatuses"/> carries: the
|
|
/// record's generated <c>Equals</c> compares the sample list by REFERENCE.</para>
|
|
/// </param>
|
|
/// <param name="Diagnostics">
|
|
/// Operator-facing driver diagnostics from <c>IDriverDiagnostics.GetDiagnostics()</c> (e.g. S7's
|
|
/// negotiated PDU size), bounded and in ordinal key order; null when the driver does not implement the
|
|
/// capability. Additive, never a state change. Same by-reference value-equality caveat as
|
|
/// <paramref name="HostStatuses"/>.
|
|
/// </param>
|
|
public sealed record DriverHealthChanged(
|
|
string ClusterId,
|
|
string DriverInstanceId,
|
|
string State,
|
|
DateTime? LastSuccessfulReadUtc,
|
|
string? LastError,
|
|
int ErrorCount5Min,
|
|
DateTime PublishedUtc,
|
|
DateTime? RediscoveryNeededUtc = null,
|
|
string? RediscoveryReason = null,
|
|
IReadOnlyList<HostConnectivityStatus>? HostStatuses = null,
|
|
SkippedTagReport? SkippedTags = null,
|
|
IReadOnlyDictionary<string, string>? Diagnostics = null)
|
|
{
|
|
/// <summary>
|
|
/// DPS topic name. Both the runtime <c>AkkaDriverHealthPublisher</c> and the AdminUI
|
|
/// <c>DriverStatusSignalRBridge</c> reference this single constant so renames can't
|
|
/// silently desynchronise publisher and subscriber.
|
|
/// </summary>
|
|
public const string TopicName = "driver-health";
|
|
}
|