feat(historian): page within oversized tie clusters (#400) instead of loud-failing

This commit is contained in:
Joseph Doherty
2026-06-17 20:11:09 -04:00
parent 3699fc16a8
commit 2e6c6d3ab6
6 changed files with 368 additions and 31 deletions
@@ -41,6 +41,17 @@ public sealed class ServerHistorianOptions
/// <summary>Per-process shared secret the sidecar verifies in the Hello frame.</summary>
public string SharedSecret { get; init; } = "";
/// <summary>
/// The upper bound on the bounded over-fetch the HistoryRead-Raw paging uses to page WITHIN an
/// oversized "tie cluster" (more raw samples sharing one SourceTimestamp than the client's per-page
/// cap). When a resume read stalls on such a cluster, the node manager over-fetches up to
/// <c>MaxTieClusterOverfetch + 1</c> ties at that single timestamp (a <c>start == end</c> read) and
/// pages through them; this bounds how large a single-timestamp burst the server will buffer in
/// memory before it gives up and surfaces <c>BadHistoryOperationUnsupported</c> for that node. The
/// default (65536) comfortably covers any realistic same-millisecond burst.
/// </summary>
public int MaxTieClusterOverfetch { get; init; } = 65536;
/// <summary>Returns operator-facing misconfiguration warnings for an <c>Enabled</c> historian
/// (empty when disabled or correctly configured). Pure — the registration logs each entry.</summary>
/// <returns>Zero or more human-readable warning messages.</returns>
@@ -52,6 +63,8 @@ public sealed class ServerHistorianOptions
warnings.Add("ServerHistorian:SharedSecret is empty while the historian is enabled — the Wonderware sidecar Hello frame will carry an empty secret.");
if (Port <= 0)
warnings.Add($"ServerHistorian:Port is {Port} — must be > 0; the read client cannot dial the sidecar.");
if (MaxTieClusterOverfetch <= 0)
warnings.Add($"ServerHistorian:MaxTieClusterOverfetch is {MaxTieClusterOverfetch} — must be > 0; HistoryRead-Raw cannot page within an oversized tie cluster and will surface BadHistoryOperationUnsupported for those reads.");
return warnings;
}
}