mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-07-22 06:50:38 +02:00
f83f8afa86
recomputeStats() wrote statSum/statSamples/statMin/statMax/statsValid from inside the stats() fast path, which runs under only a shared RLock via MemoryStore.Stats -> Level.findBuffers. Two concurrent queries on the same invalid buffer could both enter the fast path and race on those fields. Require statsValid in the fast-path guard instead of recomputing inline; invalid buffers now fall through to the existing point-by-point scan, which only reads b.data. recomputeStats() is unchanged and still used by checkpoint loadFile at single-threaded load time. Updated stats_test.go: overwritten buffers now stay statsValid=false after a query (documenting non-mutating reads); TestStatsMultiBufferChain and TestStatsFastPathThenPartialTail now recompute stats after building bare buffers so the fast-path cache fold is still covered; added TestStatsConcurrentQueriesNoRace (race-clean under -race for both valid and post-overwrite buffers) and TestStatsGappedChain (real inter-buffer gap correctly excluded from Samples/Min/Max/Avg). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>