Files
lmxopcua/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/IDependencyConsumer.cs
T
Joseph Doherty 6636de1199 refactor(runtime): delete the per-value AttributeValuePublished message
It had no production sender: every driver data change is already a
batch, and the comms-loss fan was converted earlier. DependencyMuxActor
drops its per-value receive, DriverInstanceActor drops the record, and
DependencyMuxActorTests' 13 sends move to the ValuePublishes.Single
one-item batch (same semantics through the batch path). XML docs and
the living docs (DriverLifecycle, VirtualTags, ScriptEditor) are
reworded; historical plan docs are left as written.

Refs #731 #734
Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
2026-10-22 14:42:08 -04:00

45 lines
2.6 KiB
C#

namespace ZB.MOM.WW.OtOpcUa.Core.Abstractions;
/// <summary>
/// Optional composable driver capability: the driver consumes <b>other</b> tags' live values.
/// The host registers the declared <see cref="DependencyRefs"/> with its per-node dependency mux
/// and forwards every matching value change into <see cref="OnDependencyValue"/> — the seam that
/// lets a host-blind driver (e.g. the <c>Calculation</c> pseudo-driver) read the address space's
/// live values without any cross-driver plumbing of its own.
/// </summary>
/// <remarks>
/// <para>
/// The mechanism mirrors how a <c>VirtualTagActor</c> registers interest on the
/// <c>DependencyMuxActor</c>: the mux already receives every driver's
/// published values (batched, one item per value) keyed by wire-ref (under v3, RawPath), so a driver that
/// implements this interface simply piggy-backs on that fan-out. A calc tag's computed output
/// re-enters the mux via the ordinary driver publish path, so calc-of-calc chains work with no
/// extra machinery — which is exactly why the deploy-time cycle gate is mandatory.
/// </para>
/// <para>
/// Implementations of <see cref="OnDependencyValue"/> are invoked from an actor context and
/// <b>must be non-blocking</b> — do the work inline and cheaply (the compile cache makes
/// steady-state calc evaluation a bounded method invocation), never block on I/O.
/// </para>
/// </remarks>
public interface IDependencyConsumer
{
/// <summary>
/// Wire-refs (RawPaths) this driver needs fed to it, derived from its authored tags. The host
/// re-reads this after <see cref="IDriver.InitializeAsync"/> / <see cref="IDriver.ReinitializeAsync"/>
/// and (re)registers the set with its dependency mux on every apply, so a tag/script edit that
/// changes the set converges without a bespoke notification.
/// </summary>
IReadOnlyCollection<string> DependencyRefs { get; }
/// <summary>
/// Host push of a single dependency value change. Called from an actor context, so the
/// implementation must be non-blocking.
/// </summary>
/// <param name="rawPath">The changed dependency's wire-ref (RawPath).</param>
/// <param name="value">The new value (may be null).</param>
/// <param name="statusCode">The OPC UA status code carried with the value (0 = Good).</param>
/// <param name="timestampUtc">The source timestamp of the change.</param>
void OnDependencyValue(string rawPath, object? value, uint statusCode, DateTime timestampUtc);
}