docs(code): honest rationales — Akka restart semantics, per-key shards, EF literal inlining; retire or annotate orphaned members

This commit is contained in:
Joseph Doherty
2026-08-16 05:33:33 -04:00
parent dbc9223206
commit b9e9df4081
11 changed files with 133 additions and 58 deletions
@@ -29,9 +29,11 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.ScriptedAlarms;
/// </para>
///
/// <para>
/// <b>Data flow.</b> <see cref="DependencyMuxActor"/> delivers a
/// <see cref="VirtualTagActor.DependencyValueChanged"/> for every tag the loaded alarms
/// depend on; the host pushes each into the upstream. The engine self-evaluates: its own
/// <b>Data flow.</b> <see cref="DependencyMuxActor"/> delivers the values of every tag the
/// loaded alarms depend on — in production as a batched
/// <see cref="VirtualTagActor.DependencyValueBatch"/> per driver burst, with the per-value
/// <see cref="VirtualTagActor.DependencyValueChanged"/> receive retained for direct senders and
/// tests; the host pushes each into the upstream. The engine self-evaluates: its own
/// <see cref="ITagUpstreamSource.SubscribeTag"/> observer re-runs the predicates and raises
/// <see cref="ScriptedAlarmEngine.OnEvent"/>. The host does NOT call evaluate — it only
/// feeds values in and fans emissions out.
@@ -134,9 +136,10 @@ public sealed class ScriptedAlarmHostActor : ReceiveActor
/// <summary>Factory method to create Props for a <see cref="ScriptedAlarmHostActor"/>.</summary>
/// <param name="publishActor">The OPC UA publish actor that consumes
/// <see cref="OpcUaPublishActor.AlarmStateUpdate"/> bridged from engine emissions.</param>
/// <param name="mux">Optional dependency multiplexer the host registers interest with so it
/// receives a <see cref="VirtualTagActor.DependencyValueChanged"/> per dependency tag. Null on the
/// dev/Mac path (no live values).</param>
/// <param name="mux">Optional dependency multiplexer the host registers interest with so it receives
/// its dependency tags' values — a <see cref="VirtualTagActor.DependencyValueBatch"/> per burst in
/// production, or a per-value <see cref="VirtualTagActor.DependencyValueChanged"/> from a direct
/// sender or a test. Null on the dev/Mac path (no live values).</param>
/// <param name="upstream">The mux-fed upstream the engine reads + subscribes from. MUST be the
/// same instance the <paramref name="engine"/> was constructed around.</param>
/// <param name="engine">The scripted-alarm engine this host owns + disposes.</param>
@@ -403,10 +406,12 @@ public sealed class ScriptedAlarmHostActor : ReceiveActor
/// Loops the per-value handler, preserving in-burst order.</summary>
/// <remarks>
/// <b>Mid-batch exception policy: unguarded, deliberately.</b> An exception escaping
/// <see cref="OnDependencyChanged"/> drops the remaining items of this burst and restarts the actor
/// — exactly what it already did when the same values arrived as N separate messages (the tail is
/// then lost to the mailbox flush instead of to the loop), so batching changes the blast radius by
/// nothing. Catching per item is deliberately NOT done: the handler is a single
/// <see cref="OnDependencyChanged"/> drops the remaining items of this burst and restarts the actor.
/// That IS wider than the per-message path — Akka restarts do not flush the mailbox, only the
/// failing message is dropped, so as N separate messages the same fault would cost one value rather
/// than the burst's tail. Accepted: the engine tolerates a missed intermediate value (the next
/// delivery for that tag re-converges its state). Catching per item is deliberately NOT done: the
/// handler is a single
/// <c>IUpstreamValueSource.Push</c> into an in-memory cache, so a throw means the upstream itself is
/// broken and swallowing it would feed the engine a silently truncated burst. Contrast
/// <c>ContinuousHistorizationRecorder.IngestAsync</c>, which DOES catch per item because its