M3 R3.1: document the captured + validated AddStreamValues "ON" write path
revision-write-path.md §"R3.1 CAPTURED" + roadmap R3.1/R3.2/one-glance now record the validated
finding: the historical write is HistoryService.AddStreamValues ("ON" storage-sample buffer, AddS2
"OS" family) + EnsureTags, not AddNonStreamValues/TransactionService. Includes the decoded 56-byte
"ON" buffer layout, the working priming/batch sequence, the tag-GUID keying, and that the D2 cache
gate does not block the primed 2023 R2 client. Remaining work to ship AddHistoricalValuesAsync is
the managed "ON" serializer (adapt HistorianEventWriteProtocol) + gRPC orchestrator wiring.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B6mcaT2PjRFKcogzp9UkfC
This commit is contained in:
@@ -213,6 +213,43 @@ IL-rewrite `Archestra.Historian.GrpcClient.dll`; (3) write-enabled run → captu
|
||||
`tagInfos` (+ `btInput` if the gate passes); (4) build golden serializer(s) in `src/`; (5) real
|
||||
`bCommit=true` write + SQL read-back on a sandbox tag → ship `AddHistoricalValuesAsync`.
|
||||
|
||||
### R3.1 CAPTURED + VALIDATED (2026-06-21): the write rides `HistoryService.AddStreamValues` ("ON" buffer)
|
||||
|
||||
The capture ran end-to-end against the live server (`AVEVA.Historian.Grpc2023CaptureHarness`,
|
||||
`capture-write` scenario, sandbox tag created by the harness, IL-rewritten `GrpcClient` dumping every
|
||||
`byte[]`). The committed write **persisted and read back over gRPC** (SDK `ReadRawAsync` returned the
|
||||
sample) — fully validated.
|
||||
|
||||
**The roadmap's assumption was wrong.** The native non-streamed (historical backfill) write does **not**
|
||||
use `AddNonStreamValues` / the TransactionService at all. The native `HistorianAccess.AddNonStreamedValue
|
||||
→ SendValues` routes over gRPC as **`HistoryService.AddStreamValues`** carrying an **"ON"
|
||||
storage-sample buffer** (structurally the AddS2 **"OS"** family — same serializer pattern the SDK already
|
||||
has in `HistorianEventWriteProtocol`), preceded by **`EnsureTags`** to register the tag:
|
||||
|
||||
```
|
||||
EnsureTags.tagInfos (144B) = the analog CTagMetadata the SDK's EnsureTagAsync already builds
|
||||
(0x4E marker … fe 00 trailer)
|
||||
AddStreamValues.values (56B) = "ON" (0x4E4F) + u16 sampleCount(1) + u32 totalLen(56)
|
||||
+ u16 payloadLen(46) + 16B tag GUID + FILETIME(sample)
|
||||
+ u16 OpcQuality(192=Good) + u32 type/descriptor
|
||||
+ FILETIME(received/version) + 8B double value
|
||||
```
|
||||
|
||||
The full priming/write sequence that works from the native client (write-enabled session): `OpenConnection`
|
||||
→ `UpdateClientStatus` ×N → `EnsureTags` → `GetTagInfosFromName` (resolve identity) → `AddStreamValues`
|
||||
("ON" buffer). Notes: (a) the **D2 cache gate (err 129) does NOT block** the primed 2023 R2 client —
|
||||
`AddNonStreamedValue` returned success once the session was primed (via `AddTag`/`GetTagInfoByName`) and
|
||||
the server had assigned the tag key; (b) the value is keyed by a **16-byte tag GUID**, not the uint
|
||||
`tagKey` (so the SDK serializer needs the tag's GUID, available from EnsureTags/GetTagInfo, not just
|
||||
`HistorianTagMetadata.Key`); (c) batch lifecycle is `NonStreamedValuesBegin → AddNonStreamedValue →
|
||||
SendValues → AddNonStreamedValuesEnd` (End-before-Send returns err 160 InvalidBatchId).
|
||||
|
||||
**Remaining to ship `AddHistoricalValuesAsync`:** build the managed "ON" `AddStreamValues` serializer in
|
||||
`src/` (adapt `HistorianEventWriteProtocol`'s "OS" builder), resolve the tag GUID, reuse the existing
|
||||
`EnsureTagAsync` CTagMetadata, wire `HistoryService.AddStreamValues` over the gRPC orchestrator, golden-test
|
||||
the buffer, then a real write + read-back on a sandbox tag. Capture artifacts (gitignored):
|
||||
`artifacts/reverse-engineering/grpc-nonstream-capture/captureB4.ndjson`.
|
||||
|
||||
---
|
||||
|
||||
## Legacy WCF analysis (preserved — still accurate for the 2020 WCF transport)
|
||||
|
||||
Reference in New Issue
Block a user