fix(historian): #688 clamp the Gateway per-sample row budget at the gateway's default ceiling
The default MaxTimeWeightedRawRows (1,000,000) + 18 exceeded the gateway's default MaxValuesCeiling (1,000,000), so with AllowStreamingBeyondCeiling=false every Gateway per-sample aggregate read was refused. The allowance is now clamped at 1,000,000 while the cap is at or under it (RawAggregateReader. ClampToGatewayCeiling); a cap above it keeps its allowance. Raw reads are not clamped (rebased onto #686).
This commit is contained in:
@@ -47,8 +47,9 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway;
|
||||
/// SQL backends' time-weighted reads use): past it the node fails with
|
||||
/// <see cref="HistoryReadLimitExceededException"/> (⇒ <c>BadTooManyOperations</c>) once the stream — bounded by the
|
||||
/// requested row budget — has been drained. The gateway is asked for at most <c>cap + 2 + </c>
|
||||
/// <see cref="PreWindowAllowance"/> rows; a stream that delivers all of them cannot be proven complete and fails the
|
||||
/// same way rather than answering from a truncated window.
|
||||
/// <see cref="PreWindowAllowance"/> rows, clamped at <see cref="GatewayDefaultMaxValuesCeiling"/> while the cap is at
|
||||
/// or under it (#688, <see cref="ClampToGatewayCeiling"/>); a stream that delivers all of them cannot be proven
|
||||
/// complete and fails the same way rather than answering from a truncated window.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Values and status.</b> A sample's value is its numeric value (Double), else its string value, else Empty; its
|
||||
@@ -109,7 +110,29 @@ internal static class RawAggregateReader
|
||||
/// <param name="maxWindowRows">The configured cap (<= 0 = unbounded).</param>
|
||||
/// <returns>The row limit to request.</returns>
|
||||
public static int MaxValuesFor(int maxWindowRows) =>
|
||||
maxWindowRows <= 0 ? int.MaxValue : (int)Math.Min(int.MaxValue, (long)maxWindowRows + 2 + PreWindowAllowance);
|
||||
maxWindowRows <= 0 ? int.MaxValue : ClampToGatewayCeiling((long)maxWindowRows + 2 + PreWindowAllowance, maxWindowRows);
|
||||
|
||||
/// <summary>
|
||||
/// The HistorianGateway's default <c>Historian:ReadLimits:MaxValuesCeiling</c>. With
|
||||
/// <c>AllowStreamingBeyondCeiling=false</c> the gateway refuses any <c>max_values</c> above its ceiling.
|
||||
/// </summary>
|
||||
internal const int GatewayDefaultMaxValuesCeiling = 1_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// #688: a <c>ReadRaw</c> row budget of <paramref name="rows"/> plus this backend's own allowance
|
||||
/// (<paramref name="requested"/>) clamped at <see cref="GatewayDefaultMaxValuesCeiling"/> — but never below
|
||||
/// <paramref name="rows"/> itself. The allowance (the boundary row, the margin, the completeness row) must not push a
|
||||
/// budget that fits the gateway's default ceiling over it: the default <c>MaxTimeWeightedRawRows</c> (1,000,000) + 18
|
||||
/// used to exceed it, so a gateway with <c>AllowStreamingBeyondCeiling=false</c> refused EVERY per-sample read. A
|
||||
/// count above the ceiling is the operator's (or client's) deliberate choice for a streaming gateway and keeps its
|
||||
/// allowance. The cost of clamping is that a window holding within the allowance of the ceiling cannot be proven
|
||||
/// complete and fails as over the cap — the same outcome it would get one row later.
|
||||
/// </summary>
|
||||
/// <param name="requested">The budget including the allowance.</param>
|
||||
/// <param name="rows">The caller's own row count (the cap, or <c>NumValuesPerNode</c>), > 0.</param>
|
||||
/// <returns>The <c>max_values</c> to request.</returns>
|
||||
internal static int ClampToGatewayCeiling(long requested, long rows) =>
|
||||
(int)Math.Min(int.MaxValue, rows > GatewayDefaultMaxValuesCeiling ? requested : Math.Min(requested, GatewayDefaultMaxValuesCeiling));
|
||||
|
||||
/// <summary>Maps one gateway raw sample to a stored sample (value + mapped status, Empty clamped Bad).</summary>
|
||||
/// <param name="sample">The gateway sample; its timestamp must be set.</param>
|
||||
|
||||
Reference in New Issue
Block a user