probe(grpc): DeleteTagExtendedProperties multiplexed-channel — disproven

Adds an internal RE probe (HistorianGrpcTagWriteOrchestrator.
ProbeDeleteTagExtendedPropertiesAsync) testing whether gRPC's single shared
channel lifts the WCF per-connection working-set wall that blocks DelTep.

Live result (2023 R2, History iface 12): both GetTgByNm + GetTepByNm primes
succeed on the one shared channel, yet DelTep is still rejected (native code=1)
and the property survives. So the working set is populated by the native
client's in-process registration state, not the wire session — neither WCF's
per-service channels nor gRPC's shared channel reproduce it. DelTep stays
server-blocked on BOTH transports and remains unshipped.

Gated negative test DeleteTagExtendedProperties_OverGrpc_ProbeMultiplexedChannel
pins this (primes succeed, delete rejected, prop survives) and flips if a future
server/registration lifts the wall. Comment in HistorianClient records the
probe. 321 offline tests pass; live test passes bounded at ~11s.

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:55:05 -04:00
parent 32cb5152a6
commit 2bd86e4e83
3 changed files with 196 additions and 3 deletions
@@ -256,9 +256,14 @@ public sealed class HistorianClient : IAsyncDisposable
// golden-verified against a server-accepted buffer, but the SDK cannot yet make the 2020 server
// accept the delete: the server's CHistStorage::DeleteTagExtendedProperties consults a
// per-connection working set that the native client populates by multiplexing GetTepByNm and
// DelTep over ONE connection, which the SDK's per-service WCF channels don't reproduce. See the
// documented-but-blocked path in HistorianWcfTagWriteOrchestrator and
// docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete.
// DelTep over ONE connection, which the SDK's per-service WCF channels don't reproduce. The gRPC
// transport — where every service client shares ONE channel — was probed 2026-06-22 to test that
// multiplexing hypothesis (GetTgByNm + GetTepByNm prime then DelTep on one write-enabled session,
// HistorianGrpcTagWriteOrchestrator.ProbeDeleteTagExtendedPropertiesAsync): both primes succeed on
// the shared channel yet the server STILL rejects the delete (native code=1), so gRPC does not lift
// the wall either. The working set is evidently populated by the native client's in-process
// registration state, not the wire session. See the documented-but-blocked path in
// HistorianWcfTagWriteOrchestrator and docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete.
/// <summary>
/// Executes a SQL command against the Historian over the WCF <c>ExeC</c>/<c>GetR</c> ops and