RE: resolve R1.8/R1.9 analog/state summary via request+response capture
Captured the native StartQuery2 pRequestBuff and the GetNextQueryResultBuffer2 response (instrument-wcf-writemessage + chained instrument-wcf-readmessage) and decoded both against AnalogSummaryHistory SQL ground truth. Conclusion: the rich multi-aggregate analog/state summary struct is NOT delivered over the 2020 WCF binary protocol — the response is the ordinary version-9 row buffer the existing aggregate parser already handles, carrying one value per cycle selected by RetrievalMode (QueryType 5-8), not ValueSelector (inert on this path). So "analog summary" == the existing ReadAggregateAsync; no new src/ code warranted. Tooling (tools/ + scripts/ only, nothing in src/): - NativeTraceHarness: drive summary knobs via --value-selector / --aggregation-type / --max-states (uint16) / --filter - Capture-SummaryRequest.ps1: repeatable instrument+stage+matrix capture, -WithResponse chains the ReadMessage hook - decode-summary-capture.py: StartQuery2 request diff vs baseline - decode-summary-response.py: response decode vs SQL ground truth Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,13 @@ internal static class Program
|
||||
string runtimeMethodPointerFilters = GetArg(args, "--runtime-method-pointer-filters")
|
||||
?? "StartDataQuery;StartQuery;GetNextRow;StartEventQuery";
|
||||
ulong resolutionTicks = ulong.TryParse(GetArg(args, "--resolution-ticks"), out ulong parsedResolutionTicks) ? parsedResolutionTicks : 0;
|
||||
// Summary-query knobs on HistoryQueryArgs (R1.8/R1.9 capture). Left null/0 = not set,
|
||||
// so a normal Full read is unaffected. ValueSelector/AggregationType/MaxStates/Filter
|
||||
// are the native properties that turn a Cyclic/Full query into an analog/state summary.
|
||||
string? valueSelectorName = GetArg(args, "--value-selector");
|
||||
string? aggregationTypeName = GetArg(args, "--aggregation-type");
|
||||
uint maxStates = uint.TryParse(GetArg(args, "--max-states"), out uint parsedMaxStates) ? parsedMaxStates : 0;
|
||||
string? historyFilter = GetArg(args, "--filter");
|
||||
DateTime endUtc = TryParseUtc(GetArg(args, "--end-utc")) ?? DateTime.UtcNow;
|
||||
DateTime startUtc = TryParseUtc(GetArg(args, "--start-utc")) ?? endUtc.AddMinutes(-lookbackMinutes);
|
||||
|
||||
@@ -789,6 +796,26 @@ internal static class Program
|
||||
{
|
||||
SetProperty(queryArgs, "Resolution", resolutionTicks);
|
||||
}
|
||||
// Summary knobs — only set when explicitly supplied so plain reads are untouched.
|
||||
if (valueSelectorName is not null)
|
||||
{
|
||||
Type valueSelectorType = GetType(assembly, "ArchestrA.HistorianValueSelector");
|
||||
SetProperty(queryArgs, "ValueSelector", Enum.Parse(valueSelectorType, valueSelectorName, ignoreCase: true));
|
||||
}
|
||||
if (aggregationTypeName is not null)
|
||||
{
|
||||
Type aggregationType = GetType(assembly, "ArchestrA.HistorianAggregationType");
|
||||
SetProperty(queryArgs, "AggregationType", Enum.Parse(aggregationType, aggregationTypeName, ignoreCase: true));
|
||||
}
|
||||
if (maxStates > 0)
|
||||
{
|
||||
// HistoryQueryArgs.MaxStates is a UInt16 on the native wrapper.
|
||||
SetProperty(queryArgs, "MaxStates", checked((ushort)maxStates));
|
||||
}
|
||||
if (historyFilter is not null)
|
||||
{
|
||||
SetProperty(queryArgs, "Filter", historyFilter);
|
||||
}
|
||||
snapshots["QueryArgsBeforeStart"] = SnapshotObject(queryArgs);
|
||||
|
||||
startError = Activator.CreateInstance(errorType)!;
|
||||
@@ -890,6 +917,10 @@ internal static class Program
|
||||
LookbackMinutes = lookbackMinutes,
|
||||
RetrievalMode = retrievalModeName,
|
||||
ResolutionTicks = resolutionTicks,
|
||||
ValueSelector = valueSelectorName,
|
||||
AggregationType = aggregationTypeName,
|
||||
MaxStates = maxStates,
|
||||
HistoryFilter = historyFilter,
|
||||
StartUtc = startUtc.ToString("O"),
|
||||
EndUtc = endUtc.ToString("O"),
|
||||
OpenSuccess = openSuccess,
|
||||
|
||||
Reference in New Issue
Block a user