fix(historian): #693 re-review — AtTime read cap 64 + 16 per time (bursty tags need ~6)
A time inside a gap of a bursty tag costs a 64-row jump read landing in the next burst plus a bisection back across the gap (~6 reads), so the 64 + 4/time cap refused a 1 h/day 1 Hz tag asked at noon on 30/100/300 consecutive days (186/606/1,806 reads) that AVEVA's own AtTime served. The cap is a runaway guard (HistoryReadDeadline bounds wall clock): now 64 + 16 per distinct time. Regression tests for x30/x100/x300 (each <= 7 reads a time, values checked). Docs: DateTime-hinted nodes are stepped but keep the gateway's Double (the Gateway never historizes DateTime nodes; the SQL backends return DateTime).
This commit is contained in:
@@ -41,7 +41,7 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway;
|
||||
/// 2 ms the segment is the whole stretch from the known row (never a 100 ns step).
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Bounded.</b> One request may take at most <c>64 + 4 × distinct times</c> raw reads (<see cref="BaseReads"/>,
|
||||
/// <b>Bounded.</b> One request may take at most <c>64 + 16 × distinct times</c> raw reads (<see cref="BaseReads"/>,
|
||||
/// <see cref="ReadsPerTime"/>); past it — or with a strict-gateway ceiling below <see cref="MinBudget"/> rows — the
|
||||
/// node fails <c>BadTooManyOperations</c> with a message naming the limit. A jump read (to a time far past the previous
|
||||
/// read) asks for only <see cref="JumpRows"/> rows, so a thousand times spread over ten years cost about a thousand
|
||||
@@ -82,8 +82,12 @@ internal static class GatewayAtTimeReader
|
||||
/// <summary>Raw reads one request may always take …</summary>
|
||||
internal const int BaseReads = 64;
|
||||
|
||||
/// <summary>… plus this many per distinct requested time.</summary>
|
||||
internal const int ReadsPerTime = 4;
|
||||
/// <summary>
|
||||
/// … plus this many per distinct requested time. A runaway guard, not a budget (<c>HistoryReadDeadline</c> bounds the
|
||||
/// wall clock): a time inside a gap of a bursty tag legitimately costs a jump read plus a bisection back across the gap
|
||||
/// (≈ 6 reads — a 1 h/day tag asked at noon on consecutive days), so 4 refused requests AVEVA's own AtTime served.
|
||||
/// </summary>
|
||||
internal const int ReadsPerTime = 16;
|
||||
|
||||
/// <summary>The first walk-back segment's width when the window read showed no density.</summary>
|
||||
internal static readonly TimeSpan InitialWalkWidth = TimeSpan.FromMinutes(1);
|
||||
|
||||
Reference in New Issue
Block a user