docs(vtags): document runtime Historize honoring + infra-gated durable sink (Phase 1 H5)
This commit is contained in:
+4
-2
@@ -94,7 +94,9 @@ What the engine pulls driver-tag values from. Reads are **synchronous** because
|
||||
|
||||
### `IHistoryWriter`
|
||||
|
||||
Fire-and-forget sink for evaluation results when `VirtualTagDefinition.Historize = true`. Implementations must queue internally and drain on their own cadence — a slow historian must not block script evaluation. `NullHistoryWriter.Instance` is the no-op default. Today no production writer is wired into the virtual-tag path; scripted-alarm emissions flow through `Core.AlarmHistorian` via `Phase7EngineComposer.RouteToHistorianAsync` (a separate concern; see [AlarmTracking.md](AlarmTracking.md)).
|
||||
Fire-and-forget sink for evaluation results when `VirtualTagDefinition.Historize = true`. Implementations must queue internally and drain on their own cadence — a slow historian must not block script evaluation. `NullHistoryWriter.Instance` is the no-op default. Scripted-alarm emissions flow through `Core.AlarmHistorian` via `Phase7EngineComposer.RouteToHistorianAsync` (a separate concern; see [AlarmTracking.md](AlarmTracking.md)).
|
||||
|
||||
**Equipment-namespace path (H5).** The `Historize` flag is threaded end-to-end on the equipment path: `VirtualTag.Historize` → composer + artifact-decode (byte-parity) → `EquipmentVirtualTagPlan.Historize` → `VirtualTagHostActor`, which calls `IHistoryWriter.Record(nodeId, snapshot)` for every historized result (in addition to publishing the live value). The writer is injectable via DI — `DriverHostActor` resolves `IHistoryWriter` (`TryAddSingleton`, `NullHistoryWriter` default) and threads it into `VirtualTagHostActor`. **The durable AVEVA data-value sink is infra-gated**: the Wonderware historian sidecar exposes only HistoryRead + alarm-event writes (no live-data `WriteDataValues` RPC), so the production default stays `NullHistoryWriter` until that backend exists. A deployment can bind a custom `IHistoryWriter` via DI today.
|
||||
|
||||
## Dispatch integration
|
||||
|
||||
@@ -112,7 +114,7 @@ Per [ADR-002](v2/implementation/adr-002-driver-vs-virtual-dispatch.md) Option B,
|
||||
`ITagUpstreamSource` and `IHistoryWriter` are the two ports the engine requires from its host. Both live in `Core.VirtualTags`. In the v2 actor system:
|
||||
|
||||
- **Upstream-tag feed.** `DependencyMuxActor` (`src/Server/ZB.MOM.WW.OtOpcUa.Runtime/VirtualTags/DependencyMuxActor.cs`) routes `DriverInstanceActor.AttributeValuePublished` events to the `VirtualTagActor` instances that declared interest in those tag refs. Each `VirtualTagActor` holds the in-memory per-tag dependency map; the `IVirtualTagEvaluator` (`RoslynVirtualTagEvaluator`) receives the dependency snapshot synchronously on the actor message thread. Reads of never-pushed dependency refs return `null` values in the dependency snapshot.
|
||||
- **`IHistoryWriter`** — no production implementation is wired for virtual tags; `VirtualTagEngine` receives `NullHistoryWriter` by default.
|
||||
- **`IHistoryWriter`** — the equipment-namespace path threads `Historize` end-to-end and `VirtualTagHostActor` invokes the injected writer on historized results (H5); the writer is resolved through `DriverHostActor` DI with a `NullHistoryWriter` default. The standalone `VirtualTagEngine` likewise receives `NullHistoryWriter` by default. No *durable* writer ships because the historian sidecar has no live-data write RPC (infra-gated) — see the `IHistoryWriter` section above.
|
||||
|
||||
## Composition
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ Forward-looking reservations or out-of-repo; left out unless explicitly pulled b
|
||||
- Monaco InlayHints — parameter-name hints; likely intended-permanent stub.
|
||||
- The full **HistoryUpdate service** — infra-gated (no backend insert/replace/delete RPC).
|
||||
- Galaxy `ExecuteWrite` fire-and-forget write-outcome — lives in the **mxaccessgw sibling repo**, not here.
|
||||
- **Durable AVEVA virtual-tag history sink** (the concrete `IHistoryWriter` behind H5) — infra-gated: the Wonderware historian sidecar exposes only HistoryRead + alarm-event writes, no live-data `WriteDataValues` RPC. H5 (Phase 1) wired the injectable seam with a `NullHistoryWriter` default; the durable sink needs a sidecar RPC first (same class of constraint as the HistoryUpdate service).
|
||||
|
||||
## Verification per phase
|
||||
|
||||
|
||||
Reference in New Issue
Block a user