6636de1199
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
45 lines
2.6 KiB
C#
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);
|
|
}
|