feat(historian): ServerHistorian:MaxRawValuesPerRead caps raw pages and backend reads
Review R08:1.1: an uncapped HistoryRead-Raw (NumValuesPerNode = 0) read a tag's whole window into memory on every backend (SQL TOP(int.MaxValue), QuestDB LIMIT, Gateway max_values = int.MaxValue + a second snapshot copy). New ServerHistorian:MaxRawValuesPerRead (default 10 000; <= 0 unbounded with a Validate() warning; 1 raised to 2). Each backend data source takes it, reports it as IHistorianDataSource.MaxRawValuesPerRead (the Gateway: min with a strict gateway's learned ceiling), so the node manager's existing RawPageLimit paging serves N = 0 and N > cap as pages of at most the cap with a continuation point. Independently, a backend raw read asking for 0 or more than the cap reads cap + 1 rows and is REFUSED (HistoryReadLimitExceededException => BadTooManyOperations) when the window holds more - never answered truncated, since the server's paging reads a short answer as the last page. Bound through the Host registry, the SqlServer/QuestDb providers and GatewayHistorian.CreateDataSource. Tests: options (default/binding/warnings), provider binding, Gateway unit + through a real SDK node manager (uncapped -> 999/998/998/605 + CPs), and a conformance case for the SQL backends. Refs #736 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT
This commit is contained in:
+3
-2
@@ -45,8 +45,9 @@ internal sealed class ReadTestDb
|
||||
|
||||
/// <summary>A fresh data source (fresh catalog cache) over this schema; <paramref name="clock"/> is its "now".</summary>
|
||||
public SqlServerHistorianDataSource Source(TimeProvider? clock = null,
|
||||
int maxTimeWeightedRawRows = TimeWeightedAggregator.DefaultMaxWindowRows) =>
|
||||
new(Conn, Boot, new SqlServerTagCatalog(Conn, Boot), timeProvider: clock, maxTimeWeightedRawRows: maxTimeWeightedRawRows);
|
||||
int maxTimeWeightedRawRows = TimeWeightedAggregator.DefaultMaxWindowRows, int maxRawValuesPerRead = 0) =>
|
||||
new(Conn, Boot, new SqlServerTagCatalog(Conn, Boot), timeProvider: clock, maxTimeWeightedRawRows: maxTimeWeightedRawRows,
|
||||
maxRawValuesPerRead: maxRawValuesPerRead);
|
||||
|
||||
/// <summary>Inserts a tag row and the given samples. ServerTimeUtc = source time + 1 s (so tests can tell them apart).</summary>
|
||||
public async Task<int> SeedAsync(string tag, params (DateTime T, HistorianValue V, uint Status)[] samples)
|
||||
|
||||
Reference in New Issue
Block a user