Show route churn as a whole count per minute (closes #160)
check / check (push) Waiting to run
check / check (push) Waiting to run
The status page showed route churn per second as a one-minute moving average, so a quiet feed gave a fraction such as 0.1. The average was correct. The metrics tracker now also counts prefix announcements and withdrawals, from all peers, in each clock minute. /api/v1/stats reports the count for the last full minute as route_churn_per_min in stream, in place of route_churn_per_sec. The status page shows it as "Route Churn/min". The status and home pages round messages and updates per second to whole numbers. Model: opus-5-5
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// minuteCounter counts events in each clock minute and reports the count of
|
||||
// the last full minute. It is safe for concurrent use.
|
||||
type minuteCounter struct {
|
||||
mu sync.Mutex
|
||||
now func() time.Time
|
||||
|
||||
// minute is the start of the minute that count belongs to.
|
||||
minute time.Time
|
||||
count int
|
||||
// lastMinuteCount is the count of the minute just before minute.
|
||||
lastMinuteCount int
|
||||
}
|
||||
|
||||
// add counts one event in the current minute.
|
||||
func (c *minuteCounter) add() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.moveToCurrentMinute()
|
||||
c.count++
|
||||
}
|
||||
|
||||
// lastFullMinute returns the number of events in the minute that ended most
|
||||
// recently.
|
||||
func (c *minuteCounter) lastFullMinute() int {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
c.moveToCurrentMinute()
|
||||
|
||||
return c.lastMinuteCount
|
||||
}
|
||||
|
||||
// moveToCurrentMinute starts a new count when the clock has moved into
|
||||
// another minute. The count it ends becomes the last full minute's count when
|
||||
// its minute is the one just before the current minute. Otherwise the last
|
||||
// full minute had no events. The caller holds mu.
|
||||
func (c *minuteCounter) moveToCurrentMinute() {
|
||||
minute := c.now().Truncate(time.Minute)
|
||||
if minute.Equal(c.minute) {
|
||||
return
|
||||
}
|
||||
|
||||
if minute.Sub(c.minute) == time.Minute {
|
||||
c.lastMinuteCount = c.count
|
||||
} else {
|
||||
c.lastMinuteCount = 0
|
||||
}
|
||||
|
||||
c.minute = minute
|
||||
c.count = 0
|
||||
}
|
||||
Reference in New Issue
Block a user