mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
metrics: make meter ticker respect enabled-flag
This commit is contained in:
parent
d803afd7b8
commit
6ef3c5bdcc
2 changed files with 37 additions and 33 deletions
|
|
@ -22,13 +22,7 @@ func GetOrRegisterMeter(name string, r Registry) *Meter {
|
||||||
// Be sure to call Stop() once the meter is of no use to allow for garbage collection.
|
// Be sure to call Stop() once the meter is of no use to allow for garbage collection.
|
||||||
func NewMeter() *Meter {
|
func NewMeter() *Meter {
|
||||||
m := newMeter()
|
m := newMeter()
|
||||||
arbiter.Lock()
|
arbiter.add(m)
|
||||||
defer arbiter.Unlock()
|
|
||||||
arbiter.meters[m] = struct{}{}
|
|
||||||
if !arbiter.started {
|
|
||||||
arbiter.started = true
|
|
||||||
go arbiter.tick()
|
|
||||||
}
|
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,9 +89,7 @@ func newMeter() *Meter {
|
||||||
// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
|
// Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
|
||||||
func (m *Meter) Stop() {
|
func (m *Meter) Stop() {
|
||||||
if stopped := m.stopped.Swap(true); !stopped {
|
if stopped := m.stopped.Swap(true); !stopped {
|
||||||
arbiter.Lock()
|
arbiter.remove(m)
|
||||||
delete(arbiter.meters, m)
|
|
||||||
arbiter.Unlock()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,28 +124,46 @@ func (m *Meter) tick() {
|
||||||
m.a15.Tick()
|
m.a15.Tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
// meterArbiter ticks meters every 5s from a single goroutine.
|
var arbiter = meterTicker{meters: make(map[*Meter]struct{})}
|
||||||
|
|
||||||
|
// meterTicker ticks meters every 5s from a single goroutine.
|
||||||
// meters are references in a set for future stopping.
|
// meters are references in a set for future stopping.
|
||||||
type meterArbiter struct {
|
type meterTicker struct {
|
||||||
sync.RWMutex
|
mu sync.RWMutex
|
||||||
|
|
||||||
started bool
|
started bool
|
||||||
meters map[*Meter]struct{}
|
meters map[*Meter]struct{}
|
||||||
ticker *time.Ticker
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var arbiter = meterArbiter{ticker: time.NewTicker(5 * time.Second), meters: make(map[*Meter]struct{})}
|
// add adds another *Meter ot the arbiter, and starts the arbiter ticker.
|
||||||
|
func (ma *meterTicker) add(m *Meter) {
|
||||||
// tick meters on the scheduled interval
|
ma.mu.Lock()
|
||||||
func (ma *meterArbiter) tick() {
|
defer ma.mu.Unlock()
|
||||||
for range ma.ticker.C {
|
ma.meters[m] = struct{}{}
|
||||||
ma.tickMeters()
|
if !ma.started {
|
||||||
|
ma.started = true
|
||||||
|
go ma.loop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ma *meterArbiter) tickMeters() {
|
// remove removes a meter from the set of ticked meters.
|
||||||
ma.RLock()
|
func (ma *meterTicker) remove(m *Meter) {
|
||||||
defer ma.RUnlock()
|
ma.mu.Lock()
|
||||||
for meter := range ma.meters {
|
delete(ma.meters, m)
|
||||||
meter.tick()
|
ma.mu.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop ticks meters on a 5 second interval.
|
||||||
|
func (ma *meterTicker) loop() {
|
||||||
|
ticker := time.NewTicker(5 * time.Second)
|
||||||
|
for range ticker.C {
|
||||||
|
if !metricsEnabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ma.mu.RLock()
|
||||||
|
for meter := range ma.meters {
|
||||||
|
meter.tick()
|
||||||
|
}
|
||||||
|
ma.mu.RUnlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,18 +28,12 @@ func TestGetOrRegisterMeter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMeterDecay(t *testing.T) {
|
func TestMeterDecay(t *testing.T) {
|
||||||
ma := meterArbiter{
|
|
||||||
ticker: time.NewTicker(time.Millisecond),
|
|
||||||
meters: make(map[*Meter]struct{}),
|
|
||||||
}
|
|
||||||
defer ma.ticker.Stop()
|
|
||||||
m := newMeter()
|
m := newMeter()
|
||||||
ma.meters[m] = struct{}{}
|
|
||||||
m.Mark(1)
|
m.Mark(1)
|
||||||
ma.tickMeters()
|
m.tick()
|
||||||
rateMean := m.Snapshot().RateMean()
|
rateMean := m.Snapshot().RateMean()
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
ma.tickMeters()
|
m.tick()
|
||||||
if m.Snapshot().RateMean() >= rateMean {
|
if m.Snapshot().RateMean() >= rateMean {
|
||||||
t.Error("m.RateMean() didn't decrease")
|
t.Error("m.RateMean() didn't decrease")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue