Draw every panel figure from the latest sample instead of holding the totals
This commit is contained in:
@@ -55,26 +55,10 @@ 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
|
||||
}
|
||||
|
||||
// Everything the display reads, taken at one instant, so a pair of these
|
||||
// describes both the rates and the errors over the span between them.
|
||||
type counterSet struct {
|
||||
@@ -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.
|
||||
|
||||
+2
-5
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user