From fbfcabda7e6fb44149f8e97783033014d653ddc8 Mon Sep 17 00:00:00 2001 From: flamingcow Date: Tue, 4 Aug 2026 13:49:21 -0700 Subject: [PATCH] Draw every panel figure from the latest sample instead of holding the totals --- main.go | 30 ++++-------------------------- main_test.go | 7 ++----- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/main.go b/main.go index 1b68ba0..bd94699 100644 --- a/main.go +++ b/main.go @@ -55,24 +55,8 @@ type direction struct { drops uint64 base counterSet - heldFrames heldValue - heldBytes heldValue - nic atomic.Uint64 - poller *nicPoller -} - -// Monotonic totals climb by tens of thousands per frame, which is unreadable -// churn at 60Hz, so the drawn value is held and refreshed a few times a second. -type heldValue struct { - v uint64 - at time.Time -} - -func (h *heldValue) get(now time.Time, cur uint64) uint64 { - if now.Sub(h.at) >= totalsHold { - h.v, h.at = cur, now - } - return h.v + nic atomic.Uint64 + poller *nicPoller } // Everything the display reads, taken at one instant, so a pair of these @@ -238,8 +222,6 @@ func (d *direction) reset() { d.win.push(d.base) d.mu.Unlock() - d.heldFrames = heldValue{} - d.heldBytes = heldValue{} d.cable.reset() } @@ -361,7 +343,7 @@ func (d *direction) sample() { // Draws what the sampler last put in the ring rather than reading the counters // again, so the display never participates in the measurement. -func (d *direction) displayView(t time.Time) view { +func (d *direction) displayView() view { d.mu.Lock() n := d.win.count() if n == 0 { @@ -377,9 +359,6 @@ func (d *direction) displayView(t time.Time) view { v.txGbps = d.win.latest(txRateGbps) v.rxGbps = d.win.latest(rxRateGbps) d.mu.Unlock() - - v.rxFrames = d.heldFrames.get(t, v.rxFrames) - v.rxBytes = d.heldBytes.get(t, v.rxBytes) return v } @@ -569,7 +548,6 @@ const ( // How far back the shown errors reach and how many buckets the median runs // over, so a step in the rate lands half this late. rateWindowSpan = time.Second - totalsHold = 50 * time.Millisecond ) // One sampler for both directions, so they are read back to back on one clock @@ -734,7 +712,7 @@ func run(aName, bName string, nsPerM float64) error { start = resetAll(dirs, stats) } for i, d := range dirs { - views[i] = d.displayView(now) + views[i] = d.displayView() } // Empty until the probe has a stamp from each direction, so the // panel shows nothing there rather than a placeholder. diff --git a/main_test.go b/main_test.go index 43a28d5..07edfe4 100644 --- a/main_test.go +++ b/main_test.go @@ -1,9 +1,6 @@ package main -import ( - "testing" - "time" -) +import "testing" // A reset re-bases from a fresh capture while the ring still holds buckets from // just before it, so the newest bucket must not be left behind the new origin. @@ -22,7 +19,7 @@ func TestResetDoesNotUnderflowTotals(t *testing.T) { d.rxStats[0].bytes.Store(9600) d.reset() - v := d.displayView(time.Now()) + v := d.displayView() if v.rxFrames != 0 { t.Errorf("rxFrames = %d, want 0", v.rxFrames) }