v1.3.0 — rollup.js migration compat + reactor stall fixes
Query: rollup.js migration compatibility (opt-in, defaults unchanged)
Two per-request options for readers migrating from rollup.js-style aggregation, available on both the JSON and protobuf query interfaces:
bucketAlignment: "start"(bucket_alignment): anchors the bucket grid atstartTimeinstead of the epoch —bucket = startTime + floor((ts−startTime)/interval)·interval. Labels remain bucket starts, empty buckets remain omitted,endTimeremains inclusive. Unknown values are rejected withINVALID_QUERY. Anchored queries take a single query plan on every data placement, so results cannot depend on where the data lives.booleansAsNumeric: true(booleans_as_numeric): boolean fields aggregate arithmetically as 1.0/0.0 (avgof[t,t,f,t,f]=0.6) and are returned as numbers, raw reads included. Strings remain non-numeric. A boolean series whose read fails under this flag reportsQUERY_INCOMPLETErather than silently substituting a latest-per-bucket value.
The canonical defaults — epoch-aligned buckets, booleans as non-numeric latest-per-bucket — are unchanged.
Reactor stall elimination on the query path
A production incident (2 vCPU container) showed reactor stalls up to 980 ms during large queries. Root cause was an accidentally quadratic per-series merge in the fallback aggregation path, compounded by zero yield points across aggregation and response serialization.
- The shard-side map phase now emits one compact raw partial per series (O(N), was O(K²·N)): the incident shape (195 series / 3.5M points) dropped from ~5,100 ms to well under 1 ms of map-phase work.
- The full aggregation chain, protobuf response encoder, JSON response formatter, and series discovery are now coroutines that yield to the reactor on bounded chunks. End-to-end reproduction of the incident workload logs zero reactor stall warnings (was: stalls up to 980 ms), with server-side execution around 200 ms.
- NaN handling in the raw merge paths now matches the documented policy on every path (NaN never folds, never counts); pinned by new merge-correctness tests.
- New perf gate:
AggregationStallBenchmeasures both wall time and the longest reactor monopolization via a concurrent probe.
CI
- The
SinglePointEncodeCostwall-clock pins skip under unoptimized/instrumented builds; the Coverage job is green again.
Suite: 3,586 C++ unit tests, all perf gates, 184 jest + 8 standalone API tests.