docs(grpc): matrix + plan reflect ext-prop fix, SQL prime result, ConnStatus

- README transport matrix: GetTagExtendedProperties notes the multi-property parser
  fix; AddTagExtendedProperties read-back now round-trips; GetConnectionStatus gRPC
  -> live-verified; ExecuteSqlCommand notes the RegisterTags prime does not help.
  Refresh the closing production-pattern guidance.
- grpc-tooling-completion.md: mark #5 (ConnStatus) done, #4 (SQL prime) negative, and
  the #1 ext-prop read-back follow-up done.

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:
Joseph Doherty
2026-06-22 06:03:59 -04:00
parent 8984dac1ed
commit ecf446965a
2 changed files with 30 additions and 20 deletions
+22 -13
View File
@@ -50,9 +50,13 @@ transiently reject right after the create commits and on target-name collision
pre-cleans both names and retries rename (4×); callers should likewise retry. (b) **reading a written
extended property back** via `GetTagExtendedPropertiesAsync` hits a shared-parser evidence gap (value
marker `0x01` where the parser expects compact-string `0x09`) — a read-side gap, not a write failure;
the test tolerates it. Lifecycle test is self-cleaning and asserts no litter remains (verified two
consecutive clean passes). Next read-side follow-up: capture the `0x01` extended-property value
encoding and extend `HistorianTagExtendedPropertyProtocol.ParseResponse`.
the test tolerates it. Lifecycle test is self-cleaning and best-effort cleans up (rename is async +
the browse/metadata view is eventually consistent, so a hard absence assert would be racy).
**Read-side follow-up DONE 2026-06-22:** captured the live `GetTagExtendedPropertiesFromName` bytes
and fixed the parser — the response is one group per property (tag name repeats) with a **uint16
searchability-flags trailer** per property (e.g. `0x0003` built-in, `0x0001` user-added), NOT the
1-byte group trailer the old model assumed (which drifted one byte per group → `0x09`-vs-`0x01`). A
written prop now round-trips end-to-end live; golden multi-group test added.
_Original notes:_
- **Goal:** flip the 🧪 writes to ✅ by running the gated lifecycle test against a sandbox tag.
@@ -115,18 +119,23 @@ _Original notes (still the reference for the registration replay):_
"capture first, never guess"). Depends on #2 (same CM_EVENT registration).
- **Risk:** high / blocked on capture. Lowest priority.
### 4. (Stretch) SQL server-wall investigation
### 4. (Stretch) SQL server-wall investigation — ❌ RegisterTags prime does NOT help (2026-06-22)
- `ExecuteSqlCommand` over gRPC faults server-side in `CSrvDbConnection.ExecuteSqlCommand`
(IndexOutOfRange / native err 38) — a DB-connection precondition the managed session
doesn't establish. Next avenue: try a `HistoryService.RegisterTags`-family prime before
`ExecuteSqlCommand` (same fix that unblocked the M3 write path / OpenStorageConnection
class of wall). If it works, replace the bounded throw in `HistorianGrpcSqlClient` with
the real GetNextQueryResultBuffer fetch loop (already written there) and flip the test.
(IndexOutOfRange / native err 38). Tried the `HistoryService.RegisterTags`-family prime
before `ExecuteSqlCommand` on both read-only (0x402) and write-enabled (0x401) sessions:
it does **not** clear the wall — `RegisterTags` itself returned false and `ExecuteSqlCommand`
faulted with the identical native-38 error (decoded buffer: `...CSrvDbConnection.ExecuteSqlCommand
... System.IndexOutOfRangeException`). So unlike OpenStorageConnection, the SQL DB-connection
context is NOT established by the RegisterTags family. The op stays bounded behind
`ProtocolEvidenceMissingException`; use WCF for SQL. Remaining avenues are deeper (reproduce
the server-side DB connection-string/index setup the native client triggers) — low priority.
### 5. (Optional) GetConnectionStatus over gRPC
- Currently WCF-only, synthesized from an authenticated probe (no dedicated RPC either
transport). Could synthesize the same over gRPC via `StatusService.PingServer` /
`GetHistorianConsoleStatus`. Low value; do only if parity is wanted.
### 5. GetConnectionStatus over gRPC — ✅ DONE 2026-06-22
- `HistorianGrpcStatusClient.GetConnectionStatusAsync` synthesizes the status from a measured
gRPC handshake (OpenConnection yielding a storage-session GUID ⇒ connected), mirroring the WCF
synthesize-from-probe approach. Routed in `Historian2020ProtocolDialect` on `UseGrpc` (the WCF
path used the MDAS binding, which can't reach the gRPC port). Live-verified; store-forward
connectivity stays false (D2-gated). Gated test `GetConnectionStatusAsync_OverGrpc_ReportsConnected`.
### Out of scope
- `ReadBlocks` (`StartBlockRetrievalQuery`) — never captured on either transport; leave