From 4c34b9efcd539c819648c927d7e3f53220df8ad2 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Wed, 25 Feb 2026 22:58:40 +0200 Subject: Fix stream paused scrolling and apply pending TUI/probe updates --- internal/statsengine/engine.go | 29 +++++++++++++++++++++++++++++ internal/statsengine/engine_reset_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 internal/statsengine/engine_reset_test.go (limited to 'internal/statsengine') diff --git a/internal/statsengine/engine.go b/internal/statsengine/engine.go index fd46cc3..1ef58cf 100644 --- a/internal/statsengine/engine.go +++ b/internal/statsengine/engine.go @@ -16,6 +16,7 @@ type Engine struct { now func() time.Time startedAt time.Time + topN int totalSyscalls uint64 totalErrors uint64 @@ -72,6 +73,7 @@ func newEngineWithClock(topN int, now func() time.Time) *Engine { return &Engine{ now: now, startedAt: now(), + topN: topN, syscalls: newSyscallAccumulator(), files: newFileRankerWithConfig(topN), processes: newProcessAccumulatorWithConfig(topN), @@ -83,6 +85,33 @@ func newEngineWithClock(topN int, now func() time.Time) *Engine { } } +// Reset clears all accumulated stats and restarts series baselines. +func (e *Engine) Reset() { + if e == nil { + return + } + + e.mu.Lock() + defer e.mu.Unlock() + + e.startedAt = e.now() + e.totalSyscalls = 0 + e.totalErrors = 0 + e.totalBytes = 0 + e.totalReadBytes = 0 + e.totalWriteBytes = 0 + e.totalLatency = 0 + e.totalGap = 0 + e.syscalls = newSyscallAccumulator() + e.files = newFileRankerWithConfig(e.topN) + e.processes = newProcessAccumulatorWithConfig(e.topN) + e.latencyHist = newHistogram() + e.gapHist = newHistogram() + e.latencySeries = newRingTimeSeries() + e.gapSeries = newRingTimeSeries() + e.throughputSeries = newRingTimeSeries() +} + // Ingest updates all aggregates for one event pair. func (e *Engine) Ingest(pair *event.Pair) { if e == nil || pair == nil { diff --git a/internal/statsengine/engine_reset_test.go b/internal/statsengine/engine_reset_test.go new file mode 100644 index 0000000..7a86c86 --- /dev/null +++ b/internal/statsengine/engine_reset_test.go @@ -0,0 +1,27 @@ +package statsengine + +import ( + "testing" + "time" + + "ior/internal/types" +) + +func TestEngineResetClearsAccumulatedStats(t *testing.T) { + e := NewEngine(8) + e.Ingest(newEnginePair(types.SYS_ENTER_READ, 7, types.READ_CLASSIFIED, "test", 1, "/tmp/a", 7, 1000, 50)) + before := e.Snapshot() + if before.TotalSyscalls == 0 { + t.Fatalf("expected non-zero totals before reset") + } + + time.Sleep(1 * time.Millisecond) + e.Reset() + after := e.Snapshot() + if after.TotalSyscalls != 0 || after.TotalBytes != 0 || after.TotalErrors != 0 { + t.Fatalf("expected totals cleared after reset, got %+v", after) + } + if after.Elapsed > 2*time.Second { + t.Fatalf("expected elapsed to restart near zero, got %s", after.Elapsed) + } +} -- cgit v1.2.3