feat: HistorianSession browse + metadata on the reused session (+ env-gated round-trip)

Browse mirrors ReadRawAsync (collect-then-yield); metadata mirrors ReadAtTimeAsync
(unary). Delegates to the HistorianGrpcTagClient …OnSession seams so a leased session
browses + reads metadata without re-handshaking (pending.md A1 broadening).

Claude-Session: https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii
This commit is contained in:
Joseph Doherty
2026-06-25 10:28:44 -04:00
parent 2f689cbe71
commit 81aff03748
2 changed files with 38 additions and 2 deletions
@@ -53,7 +53,21 @@ public sealed class HistorianSessionRoundTripTests
await session.PingAsync(CancellationToken.None); // must not throw
_output.WriteLine("4) ping -> ok");
_output.WriteLine("session round-trip OK (write+read+status+ping on one session)");
// 5) metadata + browse on the SAME session (no re-handshake)
HistorianTagMetadata? meta = await session.GetTagMetadataAsync(sandboxTag, CancellationToken.None);
Assert.NotNull(meta);
_output.WriteLine("5) metadata -> ok");
List<string> browsed = [];
await foreach (string n in session.BrowseTagNamesAsync("*", CancellationToken.None))
{
browsed.Add(n);
if (browsed.Count >= 5) break;
}
Assert.NotEmpty(browsed);
_output.WriteLine($"6) browse rows={browsed.Count}");
_output.WriteLine("session round-trip OK (write+read+status+ping+metadata+browse on one session)");
}
// verbatim copy of BuildOptions from HandshakeReuseSpikeTests