docs: fill missing XML docs and strip tracking IDs from src comments
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.
This commit is contained in:
@@ -36,7 +36,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
public sealed record InitializeSucceeded(int Generation);
|
||||
public sealed record InitializeFailed(string Reason, int Generation);
|
||||
public sealed record DisconnectObserved(string Reason);
|
||||
/// <summary>#477 — sent to the parent (<see cref="DriverHostActor"/>) on every connectivity transition:
|
||||
/// <summary>Sent to the parent (<see cref="DriverHostActor"/>) on every connectivity transition:
|
||||
/// <c>Connected=true</c> on entering the Connected state, <c>false</c> on entering Reconnecting. The host
|
||||
/// annotates this driver's native alarm conditions' source-data Quality from it (comms lost → Bad,
|
||||
/// restored → Good) — independently of alarm transitions, since a comms-lost driver emits no alarm
|
||||
@@ -44,8 +44,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
public sealed record ConnectivityChanged(string DriverInstanceId, bool Connected);
|
||||
|
||||
/// <summary>
|
||||
/// Sent to the parent from <see cref="PostRestart"/> so the host re-provisions THIS incarnation
|
||||
/// (archreview 03/S6, 03/S16).
|
||||
/// Sent to the parent from <see cref="PostRestart"/> so the host re-provisions THIS incarnation.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A supervision restart recreates the actor object in place: the desired subscription sets are gone
|
||||
@@ -113,7 +112,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// (<c>DriverHostActor.FanCommsLossToDependencyMux</c>), which was the last sender to fabricate this
|
||||
/// message, now fabricates a batch too. The dependency mux still accepts it for tests and direct senders.
|
||||
/// <para><paramref name="StatusCode"/> is the driver's full OPC UA status code including its sub-code
|
||||
/// (#519) — not a severity bucket. Classify it with <see cref="OpcUaStatus.IsGood"/> and friends rather
|
||||
/// — not a severity bucket. Classify it with <see cref="OpcUaStatus.IsGood"/> and friends rather
|
||||
/// than comparing it to <see cref="OpcUaStatus.Good"/>.</para></summary>
|
||||
public sealed record AttributeValuePublished(string DriverInstanceId, string FullReference, object? Value, uint StatusCode, DateTime TimestampUtc);
|
||||
/// <summary>One value within an <see cref="AttributeValueBatchPublished"/>.
|
||||
@@ -123,7 +122,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
public readonly record struct AttributeValueItem(string FullReference, object? Value, uint StatusCode, DateTime TimestampUtc);
|
||||
/// <summary>Batched form of <see cref="AttributeValuePublished"/> — every changed attribute of ONE
|
||||
/// driver production burst in one message. The parent fans the whole batch to the mux and the OPC UA
|
||||
/// publish path in one hop each. Status codes ride verbatim (#519).</summary>
|
||||
/// publish path in one hop each. Status codes ride verbatim.</summary>
|
||||
public sealed record AttributeValueBatchPublished(string DriverInstanceId, IReadOnlyList<AttributeValueItem> Items);
|
||||
private sealed record DataChangeForward(string FullReference, DataValueSnapshot Snapshot);
|
||||
/// <summary>Self-sent when a batch-capable driver (<see cref="IBatchSubscribable"/>) raises
|
||||
@@ -153,9 +152,9 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// behaviour for the same reason as <see cref="RediscoveryRaised"/> — a probe tick can land while the
|
||||
/// driver is between connects.</summary>
|
||||
private sealed record HostStatusRaised;
|
||||
/// <summary>Self-sent when the wrapped driver raises <see cref="IDriverConnectionLossSource.ConnectionLost"/> (#676)
|
||||
/// <summary>Self-sent when the wrapped driver raises <see cref="IDriverConnectionLossSource.ConnectionLost"/>
|
||||
/// — it KNOWS its connection is gone for good. Marshals the event off the driver's thread. Acted on only in
|
||||
/// Connected (it becomes a disconnect at once, instead of after the #527 watchdog's silence window); every other
|
||||
/// Connected (it becomes a disconnect at once, instead of after the watchdog's silence window); every other
|
||||
/// behaviour is already reconnecting or connecting and ignores it.</summary>
|
||||
private sealed record ConnectionLossRaised(DriverConnectionLossEventArgs Args);
|
||||
|
||||
@@ -170,7 +169,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
/// <summary>
|
||||
/// How long a Connected driver may go without a single successful read — while also reporting
|
||||
/// itself non-Healthy — before the actor declares comms lost (Gitea #527). Evaluated on the
|
||||
/// itself non-Healthy — before the actor declares comms lost. Evaluated on the
|
||||
/// existing <see cref="HealthPollInterval"/> tick, so the effective detection granularity is
|
||||
/// 30 s and the worst-case detection latency is this value plus one tick.
|
||||
/// </summary>
|
||||
@@ -178,8 +177,8 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// 90 s = three health-poll ticks. Long enough that a device answering slowly under load is not
|
||||
/// torn down, short enough that an operator watching a dead PLC sees it inside two minutes.
|
||||
/// Hardcoded rather than exposed in appsettings, matching <see cref="HealthPollInterval"/> and
|
||||
/// <see cref="DefaultReconnectInterval"/>. Unlike the periodic drift-detector removed by Gitea
|
||||
/// #523, this generates <b>no</b> outbound traffic on a healthy system: the watchdog is a local
|
||||
/// <see cref="DefaultReconnectInterval"/>. Unlike the periodic drift-detector removed earlier,
|
||||
/// this generates <b>no</b> outbound traffic on a healthy system: the watchdog is a local
|
||||
/// read of <see cref="IDriver.GetHealth"/>, and it only reaches the network once a driver has
|
||||
/// already stopped reading successfully.
|
||||
/// </remarks>
|
||||
@@ -202,7 +201,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
private readonly TimeSpan _healthPollInterval;
|
||||
|
||||
/// <summary>Comms-loss watchdog threshold (#527); <see cref="TimeSpan.Zero"/> or negative disables it.</summary>
|
||||
/// <summary>Comms-loss watchdog threshold; <see cref="TimeSpan.Zero"/> or negative disables it.</summary>
|
||||
private readonly TimeSpan _commsLossTimeout;
|
||||
|
||||
/// <summary>When the actor last entered <c>Connected</c>. The comms-loss watchdog's baseline for a
|
||||
@@ -274,14 +273,14 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// newly-added alarm for the life of the connection. Empty whenever no handle is held.</para></summary>
|
||||
private IReadOnlyList<string> _subscribedAlarmRefs = Array.Empty<string>();
|
||||
|
||||
/// <summary>#662 — consecutive <see cref="HandleSubscribeAlarmsAsync"/> failures; reset on success and on
|
||||
/// <summary>Consecutive <see cref="HandleSubscribeAlarmsAsync"/> failures; reset on success and on
|
||||
/// <see cref="DetachAlarmSource"/> (a new connection starts a new streak).</summary>
|
||||
private int _alarmSubscribeFailures;
|
||||
|
||||
/// <summary>#662 — health-poll ticks the alarm reconcile still skips before its next retry (backoff).</summary>
|
||||
/// <summary>Health-poll ticks the alarm reconcile still skips before its next retry (backoff).</summary>
|
||||
private int _alarmRetrySkipTicks;
|
||||
|
||||
/// <summary>#662 — backoff cap: at the production 30 s tick a failing alarm subscribe is retried at least
|
||||
/// <summary>Backoff cap: at the production 30 s tick a failing alarm subscribe is retried at least
|
||||
/// every 4 minutes.</summary>
|
||||
private const int MaxAlarmRetrySkipTicks = 7;
|
||||
|
||||
@@ -305,7 +304,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// <param name="healthPollInterval">Optional period of the health-poll heartbeat, which also drives the
|
||||
/// subscription reconcile (<see cref="ReconcileSubscription"/>); defaults to
|
||||
/// <see cref="HealthPollInterval"/>. Exists so a test can drive the reconcile without waiting 30 s.</param>
|
||||
/// <param name="commsLossTimeout">Optional comms-loss watchdog threshold (#527); defaults to
|
||||
/// <param name="commsLossTimeout">Optional comms-loss watchdog threshold; defaults to
|
||||
/// <see cref="DefaultCommsLossTimeout"/>. <see cref="TimeSpan.Zero"/> disables the watchdog — used by
|
||||
/// tests that need a Connected driver to stay Connected while reporting non-Healthy.</param>
|
||||
/// <returns>A <see cref="Akka.Actor.Props"/> instance configured to create the wrapped <see cref="DriverInstanceActor"/>.</returns>
|
||||
@@ -343,7 +342,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
{
|
||||
var isWindowsOnly = driverType is "Galaxy";
|
||||
if (!OperatingSystem.IsWindows() && isWindowsOnly) return true;
|
||||
// R3-04 (theme 4 guard): GossipedRolesHave, not a bare "dev" literal Contains — the same
|
||||
// GossipedRolesHave, not a bare "dev" literal Contains — the same
|
||||
// case-insensitivity the rest of the role authority gives every other consumer.
|
||||
if (RoleParser.GossipedRolesHave(roles, RoleParser.Dev) && isWindowsOnly) return true;
|
||||
return false;
|
||||
@@ -361,7 +360,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// defaults to <see cref="NullDriverCapabilityInvoker"/> (pass-through) when null.</param>
|
||||
/// <param name="healthPollInterval">Period of the health-poll heartbeat, which also drives the
|
||||
/// subscription reconcile; defaults to <see cref="HealthPollInterval"/> when null.</param>
|
||||
/// <param name="commsLossTimeout">Comms-loss watchdog threshold (#527); defaults to
|
||||
/// <param name="commsLossTimeout">Comms-loss watchdog threshold; defaults to
|
||||
/// <see cref="DefaultCommsLossTimeout"/> when null, and is disabled when zero or negative.</param>
|
||||
public DriverInstanceActor(
|
||||
IDriver driver,
|
||||
@@ -411,14 +410,11 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
Timers.StartPeriodicTimer("health-poll", HealthPollTick.Instance, _healthPollInterval);
|
||||
}
|
||||
|
||||
// Ask the host to re-provision this incarnation - see ReprovisionRequested for why a supervision
|
||||
// restart otherwise leaves a dead child. base.PostRestart runs first because it runs PreStart, which
|
||||
// re-attaches the rediscovery / host-status sources and restarts the health timer; the reprovision
|
||||
// is the part PreStart cannot do, since only the host knows this driver's config and desired set.
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Ask the host to re-provision this incarnation — see <see cref="ReprovisionRequested"/> for why a
|
||||
/// supervision restart otherwise leaves a dead child. <c>base.PostRestart</c> runs first because it
|
||||
/// runs <see cref="PreStart"/>, which re-attaches the rediscovery / host-status sources and restarts
|
||||
/// the health timer; the reprovision is the part <see cref="PreStart"/> cannot do, since only the
|
||||
/// host knows this driver's config and desired set.
|
||||
/// </remarks>
|
||||
protected override void PostRestart(Exception reason)
|
||||
{
|
||||
base.PostRestart(reason);
|
||||
@@ -500,17 +496,17 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
private void Connected()
|
||||
{
|
||||
// #477 — announce connectivity to the host so it can clear any comms-lost Quality annotation on this
|
||||
// Announce connectivity to the host so it can clear any comms-lost Quality annotation on this
|
||||
// driver's native alarm conditions (Bad → Good). Fire-and-forget; the host defaults conditions to a
|
||||
// non-Good "waiting for initial data" quality at materialise, and this is what confirms them Good.
|
||||
Context.Parent.Tell(new ConnectivityChanged(_driverInstanceId, Connected: true));
|
||||
|
||||
// #527 — baseline for the comms-loss watchdog. Re-stamped on every Connected entry so a driver that
|
||||
// Baseline for the comms-loss watchdog. Re-stamped on every Connected entry so a driver that
|
||||
// reconnects but never manages a read is measured from THIS connect, not from a stale earlier one.
|
||||
_connectedSinceUtc = DateTime.UtcNow;
|
||||
|
||||
Receive<DisconnectObserved>(msg => HandleDisconnectObserved(msg.Reason));
|
||||
// #676 — the driver KNOWS its connection is gone (e.g. OpcUaClient: the upstream server halted or forgot the
|
||||
// The driver KNOWS its connection is gone (e.g. OpcUaClient: the upstream server halted or forgot the
|
||||
// session). Same handling as the watchdog's disconnect, minus the ~90 s of silence it would need to prove it.
|
||||
// Handled inline rather than re-told as DisconnectObserved (Reconnecting also swallows a stray DisconnectObserved).
|
||||
Receive<ConnectionLossRaised>(msg => HandleDisconnectObserved($"driver reported connection lost: {msg.Args.Reason}"));
|
||||
@@ -571,7 +567,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gitea #527 — the comms-loss watchdog. Declares a Connected driver disconnected once it has gone
|
||||
/// The comms-loss watchdog. Declares a Connected driver disconnected once it has gone
|
||||
/// <see cref="_commsLossTimeout"/> without a single successful read <b>while also</b> reporting
|
||||
/// itself non-Healthy, by self-sending <see cref="DisconnectObserved"/>.
|
||||
/// </summary>
|
||||
@@ -582,9 +578,9 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// Reconnect, so a driver that connected successfully and then lost its device stayed Connected
|
||||
/// forever: it published Bad for every tag, never re-initialised, and did not recover when the device
|
||||
/// came back — live-confirmed against a stopped Modbus fixture, which needed a node restart. Both
|
||||
/// comms-loss quality paths (#477 native conditions, #481 scripted-alarm inputs) hang off
|
||||
/// comms-loss quality paths (native conditions, scripted-alarm inputs) hang off
|
||||
/// <see cref="ConnectivityChanged"/>, so both were wired to a signal that never fired.
|
||||
/// Since Gitea #670 this is also <c>OpcUaClientDriver</c>'s only recovery path for a lost upstream
|
||||
/// This is also <c>OpcUaClientDriver</c>'s only recovery path for a lost upstream
|
||||
/// session (its in-driver SDK reconnect handler was deleted).
|
||||
/// </para>
|
||||
/// <para>
|
||||
@@ -634,7 +630,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
// Measure silence from the LATER of the last successful read and THIS connect — the grace is per
|
||||
// connection. `??` was wrong: drivers PRESERVE LastSuccessfulRead across Degraded/Faulted writes (that
|
||||
// preservation is the #527 design), so after a trip + reconnect to a device that accepts the connection
|
||||
// preservation is the watchdog design), so after a trip + reconnect to a device that accepts the connection
|
||||
// but still serves no data, the stamp is already older than the threshold and the FIRST tick of the new
|
||||
// connection re-trips — churn at health-tick cadence instead of the designed grace. `??` only ever helped
|
||||
// a driver that had never read at all.
|
||||
@@ -653,7 +649,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Periodic desired-vs-actual subscription reconcile (#488), riding the existing <c>health-poll</c>
|
||||
/// Periodic desired-vs-actual subscription reconcile, riding the existing <c>health-poll</c>
|
||||
/// tick. While Connected, a driver that has a desired subscription set but no live handle is
|
||||
/// re-subscribed.
|
||||
/// </summary>
|
||||
@@ -701,7 +697,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// #662 — the native-alarm half of <see cref="ReconcileSubscription"/>. The data reconcile above never
|
||||
/// The native-alarm half of <see cref="ReconcileSubscription"/>. The data reconcile above never
|
||||
/// looked at alarms, so an alarm subscribe that failed on (re)connect — e.g. a session not yet ready
|
||||
/// after an outage — left the feed gated for the life of the connection, with the driver Healthy and
|
||||
/// its data streaming. Re-asserts both halves the feed needs: the <c>OnAlarmEvent</c> handler
|
||||
@@ -718,7 +714,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
if (_driver is not IAlarmSource || _desiredAlarmRefs.Count == 0) return;
|
||||
if (_alarmEventHandler is null)
|
||||
{
|
||||
// Unreachable while every Connected entry attaches — so if this ever logs, something regressed #662.
|
||||
// Unreachable while every Connected entry attaches — so if this ever logs, something regressed.
|
||||
_log.Warning("DriverInstance {Id}: connected with desired alarm refs but no native-alarm handler — re-attaching (periodic reconcile)",
|
||||
_driverInstanceId);
|
||||
AttachAlarmSource();
|
||||
@@ -739,11 +735,11 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
private void Reconnecting()
|
||||
{
|
||||
// #477 — announce comms loss to the host so it annotates this driver's native alarm conditions Bad
|
||||
// Announce comms loss to the host so it annotates this driver's native alarm conditions Bad
|
||||
// (a comms-lost driver emits no alarm events, so this is the ONLY signal that the source is unreachable).
|
||||
Context.Parent.Tell(new ConnectivityChanged(_driverInstanceId, Connected: false));
|
||||
|
||||
// #527 — tear the dead transport down before re-initialising, or every retry leaks one.
|
||||
// Tear the dead transport down before re-initialising, or every retry leaks one.
|
||||
Receive<RetryConnect>(_ => InitializeAsync(_currentConfigJson ?? "{}", teardownFirst: true));
|
||||
// Fast-fail writes while reconnecting (same reason as Connecting — avoids the 8s host Ask
|
||||
// timeout on an inbound write to a transiently-down driver). Synchronous Receive.
|
||||
@@ -799,7 +795,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// <param name="teardownFirst">
|
||||
/// When true, <see cref="IDriver.ShutdownAsync"/> is awaited before <see cref="IDriver.InitializeAsync"/>
|
||||
/// — the sequence every driver's own <c>ReinitializeAsync</c> uses. Set on the <c>Reconnecting</c>
|
||||
/// retry path (#527), because several drivers <em>overwrite</em> their transport field in
|
||||
/// retry path, because several drivers <em>overwrite</em> their transport field in
|
||||
/// <c>InitializeAsync</c> without disposing the previous one: <c>ModbusDriver</c> assigns
|
||||
/// <c>_transport = _transportFactory(...)</c> and <c>MqttDriver</c> assigns <c>_connection</c>, both
|
||||
/// over an <see cref="IAsyncDisposable"/>. Re-initialising without tearing down therefore leaks one
|
||||
@@ -836,7 +832,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
"initialising anyway", driverInstanceId);
|
||||
}
|
||||
}
|
||||
// R2-10 T10: the connect path was the ONE capability call the invoker never saw, so a
|
||||
// The connect path was the ONE capability call the invoker never saw, so a
|
||||
// driver that could not connect contributed zero breaker input and the resilience panel
|
||||
// stayed quiet for a dead endpoint. Keyed on the driver-instance id (init spans the
|
||||
// whole driver, like a bulk subscribe). The Initialize policy never retries — this
|
||||
@@ -1045,7 +1041,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// Called on PostStop and on Connected → Reconnecting transitions so a stale handler doesn't push
|
||||
/// data-change / alarm events to an actor that has lost its driver connection.
|
||||
/// <para>Not for the data Unsubscribe / re-subscribe path — that uses <see cref="DetachDataSubscription"/>
|
||||
/// (#662).</para></summary>
|
||||
/// instead.</para></summary>
|
||||
private void DetachSubscription()
|
||||
{
|
||||
DetachDataSubscription();
|
||||
@@ -1054,7 +1050,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
/// <summary>Tear down the data-change (per-tag AND batch) handlers + null the data handle, leaving the
|
||||
/// native-alarm handler and handle alone.
|
||||
/// <para>#662: the data Unsubscribe / re-subscribe path used to run the full <see cref="DetachSubscription"/>,
|
||||
/// <para>The data Unsubscribe / re-subscribe path used to run the full <see cref="DetachSubscription"/>,
|
||||
/// so every deploy that re-subscribed a Connected driver's DATA also unhooked <c>OnAlarmEvent</c> and
|
||||
/// forgot the alarm handle — the alarm subscription still logged "established" but its events reached
|
||||
/// nobody until a reconnect or respawn. The two subscriptions are independent at the driver; only a lost
|
||||
@@ -1111,7 +1107,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribe the driver's <see cref="IDriverConnectionLossSource.ConnectionLost"/> (#676), if it is one,
|
||||
/// Subscribe the driver's <see cref="IDriverConnectionLossSource.ConnectionLost"/>, if it is one,
|
||||
/// marshalling each raise to the actor thread — actor state is never touched on the driver's thread. Attached
|
||||
/// once in <c>PreStart</c> and detached in <c>PostStop</c>, like <see cref="AttachRediscoverySource"/>: the
|
||||
/// <see cref="IDriver"/> instance can outlive this actor, so a per-connect attach would leak a handler (holding
|
||||
@@ -1134,7 +1130,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A connection loss reported while NOT Connected (#676): a (re)initialise is already pending or running, so
|
||||
/// A connection loss reported while NOT Connected: a (re)initialise is already pending or running, so
|
||||
/// there is nothing to tear down — and acting on it could tear down the connection that attempt is building.
|
||||
/// </summary>
|
||||
private void IgnoreConnectionLoss(ConnectionLossRaised msg) =>
|
||||
@@ -1142,8 +1138,8 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
_driverInstanceId, msg.Args.Reason);
|
||||
|
||||
/// <summary>
|
||||
/// Connected → Reconnecting on an observed disconnect — from the #527 watchdog or a driver's definitive
|
||||
/// <see cref="IDriverConnectionLossSource.ConnectionLost"/> (#676).
|
||||
/// Connected → Reconnecting on an observed disconnect — from the watchdog or a driver's definitive
|
||||
/// <see cref="IDriverConnectionLossSource.ConnectionLost"/>.
|
||||
/// </summary>
|
||||
private void HandleDisconnectObserved(string reason)
|
||||
{
|
||||
@@ -1218,7 +1214,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
}
|
||||
|
||||
/// <summary>Bounded driver diagnostics, or null when the driver is not an <see cref="IDriverDiagnostics"/>
|
||||
/// (Gitea #640). Pulled fresh and called UNGUARDED for the same reasons as
|
||||
/// implementation. Pulled fresh and called UNGUARDED for the same reasons as
|
||||
/// <see cref="CurrentSkippedTags"/>; a throwing implementation loses only the diagnostics.</summary>
|
||||
private IReadOnlyDictionary<string, string>? CurrentDiagnostics()
|
||||
{
|
||||
@@ -1295,7 +1291,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// <summary>Calls the driver's <see cref="IAlarmSource.SubscribeAlarmsAsync"/> (bounded) to register the
|
||||
/// alarm subscription that un-gates its native feed, caching the returned handle. Re-checks the guard
|
||||
/// (the desired set may have cleared, or another SubscribeAlarms may have already established a handle,
|
||||
/// while this was queued). Failures are logged and retried on the next Connected entry or health-poll reconcile tick (#662) — the feed
|
||||
/// while this was queued). Failures are logged and retried on the next Connected entry or health-poll reconcile tick — the feed
|
||||
/// stays gated until then.</summary>
|
||||
private async Task HandleSubscribeAlarmsAsync(SubscribeAlarms _)
|
||||
{
|
||||
@@ -1381,7 +1377,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
/// <summary>Forward a per-tag-only driver's data change to the parent for OPC UA publication, as a
|
||||
/// single-item batch — so the parent sees ONE message shape whether or not the driver batches.
|
||||
/// <para>The driver's status code rides through UNCHANGED (#519). This used to project it onto a
|
||||
/// <para>The driver's status code rides through UNCHANGED. This used to project it onto a
|
||||
/// 3-state Good/Uncertain/Bad enum here, which the node manager then re-expanded to a bare
|
||||
/// <c>0x80000000</c> — so no driver's sub-code ever reached a client, and the status constants each
|
||||
/// driver maintains were diagnostic in logs only.</para></summary>
|
||||
@@ -1395,7 +1391,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
|
||||
/// <summary>Forward one batch-capable driver production burst to the parent as a single message.
|
||||
/// <para>Every item's status code and timestamp ride through exactly as
|
||||
/// <see cref="OnDataChangeForward"/> carries them for a per-tag driver (#519; timestamps come from the
|
||||
/// <see cref="OnDataChangeForward"/> carries them for a per-tag driver (timestamps come from the
|
||||
/// driver's snapshot, never from this actor's clock).</para></summary>
|
||||
private void OnDataChangeBatchForward(DataChangeBatchForward msg)
|
||||
{
|
||||
@@ -1444,7 +1440,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
/// snapshot via <c>DriverStatusHub.JoinDriver</c> which reads the store directly.
|
||||
/// </summary>
|
||||
/// <returns>The health observed on this call, or null when <see cref="IDriver.GetHealth"/> threw.
|
||||
/// Returned so the caller can reuse the same observation — the #527 comms-loss watchdog rides this
|
||||
/// Returned so the caller can reuse the same observation — the comms-loss watchdog rides this
|
||||
/// call rather than polling the driver a second time and risking a different answer.</returns>
|
||||
private DriverHealth? PublishHealthSnapshot()
|
||||
{
|
||||
@@ -1476,7 +1472,7 @@ public sealed class DriverInstanceActor : ReceiveActor, IWithTimers
|
||||
// dedup would swallow. Flattened to a STRING for the same reason as the host digest — the
|
||||
// report holds an IReadOnlyList, which a tuple compares by reference.
|
||||
//
|
||||
// The diagnostics digest (Gitea #640) is the fourth instance: a diagnostic fact (S7's PDU size
|
||||
// The diagnostics digest is the fourth instance: a diagnostic fact (S7's PDU size
|
||||
// changing across a reconnect) moves none of the other components, so without it the publish
|
||||
// that carries it is deduped away. Flattened to a STRING - the bag is a dictionary, which a
|
||||
// tuple compares by reference.
|
||||
|
||||
Reference in New Issue
Block a user