check / check (push) Canceled after 0s
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 the prefixes announced or withdrawn 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
60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
package metrics
|
|
|
|
import (
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// minuteCounter counts events in each minute of the clock 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
|
|
}
|