289b30715d
This commit converts the dependency management from Godeps to the vendor folder, also switching the tool from godep to trash. Since the upstream tool lacks a few features proposed via a few PRs, until those PRs are merged in (if), use github.com/karalabe/trash. You can update dependencies via trash --update. All dependencies have been updated to their latest version. Parts of the build system are reworked to drop old notions of Godeps and invocation of the go vet command so that it doesn't run against the vendor folder, as that will just blow up during vetting. The conversion drops OpenCL (and hence GPU mining support) from ethash and our codebase. The short reasoning is that there's noone to maintain and having opencl libs in our deps messes up builds as go install ./... tries to build them, failing with unsatisfied link errors for the C OpenCL deps. golang.org/x/net/context is not vendored in. We expect it to be fetched by the user (i.e. using go get). To keep ci.go builds reproducible the package is "vendored" in build/_vendor.
119 lines
2.8 KiB
Go
119 lines
2.8 KiB
Go
package metrics
|
|
|
|
import (
|
|
"math"
|
|
"sync"
|
|
"sync/atomic"
|
|
)
|
|
|
|
// EWMAs continuously calculate an exponentially-weighted moving average
|
|
// based on an outside source of clock ticks.
|
|
type EWMA interface {
|
|
Rate() float64
|
|
Snapshot() EWMA
|
|
Tick()
|
|
Update(int64)
|
|
}
|
|
|
|
// NewEWMA constructs a new EWMA with the given alpha.
|
|
func NewEWMA(alpha float64) EWMA {
|
|
if UseNilMetrics {
|
|
return NilEWMA{}
|
|
}
|
|
return &StandardEWMA{alpha: alpha}
|
|
}
|
|
|
|
// NewEWMA1 constructs a new EWMA for a one-minute moving average.
|
|
func NewEWMA1() EWMA {
|
|
return NewEWMA(1 - math.Exp(-5.0/60.0/1))
|
|
}
|
|
|
|
// NewEWMA5 constructs a new EWMA for a five-minute moving average.
|
|
func NewEWMA5() EWMA {
|
|
return NewEWMA(1 - math.Exp(-5.0/60.0/5))
|
|
}
|
|
|
|
// NewEWMA15 constructs a new EWMA for a fifteen-minute moving average.
|
|
func NewEWMA15() EWMA {
|
|
return NewEWMA(1 - math.Exp(-5.0/60.0/15))
|
|
}
|
|
|
|
// EWMASnapshot is a read-only copy of another EWMA.
|
|
type EWMASnapshot float64
|
|
|
|
// Rate returns the rate of events per second at the time the snapshot was
|
|
// taken.
|
|
func (a EWMASnapshot) Rate() float64 { return float64(a) }
|
|
|
|
// Snapshot returns the snapshot.
|
|
func (a EWMASnapshot) Snapshot() EWMA { return a }
|
|
|
|
// Tick panics.
|
|
func (EWMASnapshot) Tick() {
|
|
panic("Tick called on an EWMASnapshot")
|
|
}
|
|
|
|
// Update panics.
|
|
func (EWMASnapshot) Update(int64) {
|
|
panic("Update called on an EWMASnapshot")
|
|
}
|
|
|
|
// NilEWMA is a no-op EWMA.
|
|
type NilEWMA struct{}
|
|
|
|
// Rate is a no-op.
|
|
func (NilEWMA) Rate() float64 { return 0.0 }
|
|
|
|
// Snapshot is a no-op.
|
|
func (NilEWMA) Snapshot() EWMA { return NilEWMA{} }
|
|
|
|
// Tick is a no-op.
|
|
func (NilEWMA) Tick() {}
|
|
|
|
// Update is a no-op.
|
|
func (NilEWMA) Update(n int64) {}
|
|
|
|
// StandardEWMA is the standard implementation of an EWMA and tracks the number
|
|
// of uncounted events and processes them on each tick. It uses the
|
|
// sync/atomic package to manage uncounted events.
|
|
type StandardEWMA struct {
|
|
uncounted int64 // /!\ this should be the first member to ensure 64-bit alignment
|
|
alpha float64
|
|
rate float64
|
|
init bool
|
|
mutex sync.Mutex
|
|
}
|
|
|
|
// Rate returns the moving average rate of events per second.
|
|
func (a *StandardEWMA) Rate() float64 {
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
return a.rate * float64(1e9)
|
|
}
|
|
|
|
// Snapshot returns a read-only copy of the EWMA.
|
|
func (a *StandardEWMA) Snapshot() EWMA {
|
|
return EWMASnapshot(a.Rate())
|
|
}
|
|
|
|
// Tick ticks the clock to update the moving average. It assumes it is called
|
|
// every five seconds.
|
|
func (a *StandardEWMA) Tick() {
|
|
count := atomic.LoadInt64(&a.uncounted)
|
|
atomic.AddInt64(&a.uncounted, -count)
|
|
instantRate := float64(count) / float64(5e9)
|
|
a.mutex.Lock()
|
|
defer a.mutex.Unlock()
|
|
if a.init {
|
|
a.rate += a.alpha * (instantRate - a.rate)
|
|
} else {
|
|
a.init = true
|
|
a.rate = instantRate
|
|
}
|
|
}
|
|
|
|
// Update adds n uncounted events.
|
|
func (a *StandardEWMA) Update(n int64) {
|
|
atomic.AddInt64(&a.uncounted, n)
|
|
}
|