| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- package metrics
- import (
- "math"
- )
- type EWMA interface {
- Clear()
- Rate() float64
- Tick()
- Update(int64)
- }
- type ewma struct {
- alpha float64
- in chan int64
- out chan float64
- reset, tick chan bool
- }
- func NewEWMA(alpha float64) EWMA {
- a := &ewma{
- alpha,
- make(chan int64),
- make(chan float64),
- make(chan bool), make(chan bool),
- }
- go a.arbiter()
- return a
- }
- func NewEWMA1() EWMA {
- return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 1))
- }
- func NewEWMA5() EWMA {
- return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 5))
- }
- func NewEWMA15() EWMA {
- return NewEWMA(1 - math.Exp(-5.0 / 60.0 / 15))
- }
- func (a *ewma) Clear() {
- a.reset <- true
- }
- func (a *ewma) Rate() float64 {
- return <-a.out * float64(1e9)
- }
- func (a *ewma) Tick() {
- a.tick <- true
- }
- func (a *ewma) Update(n int64) {
- a.in <- n
- }
- func (a *ewma) arbiter() {
- var uncounted int64
- var rate float64
- var initialized bool
- for {
- select {
- case n := <-a.in: uncounted += n
- case a.out <- rate:
- case <-a.reset:
- uncounted = 0
- rate = 0.0
- case <-a.tick:
- instantRate := float64(uncounted) / float64(5e9)
- if initialized {
- rate += a.alpha * (instantRate - rate)
- } else {
- initialized = true
- rate = instantRate
- }
- uncounted = 0
- }
- }
- }
|