@@ -20,6 +20,8 @@ type Meter interface {
2020
2121// GetOrRegisterMeter returns an existing Meter or constructs and registers a
2222// new StandardMeter.
23+ // Be sure to unregister the meter from the registry once it is of no use to
24+ // allow for garbage collection.
2325func GetOrRegisterMeter (name string , r Registry ) Meter {
2426 if nil == r {
2527 r = DefaultRegistry
@@ -28,15 +30,15 @@ func GetOrRegisterMeter(name string, r Registry) Meter {
2830}
2931
3032// NewMeter constructs a new StandardMeter and launches a goroutine.
33+ // Be sure to call Stop() once the meter is of no use to allow for garbage collection.
3134func NewMeter () Meter {
3235 if UseNilMetrics {
3336 return NilMeter {}
3437 }
3538 m := newStandardMeter ()
3639 arbiter .Lock ()
3740 defer arbiter .Unlock ()
38- m .id = arbiter .newID ()
39- arbiter .meters [m .id ] = m
41+ arbiter .meters [m ] = struct {}{}
4042 if ! arbiter .started {
4143 arbiter .started = true
4244 go arbiter .tick ()
@@ -46,6 +48,8 @@ func NewMeter() Meter {
4648
4749// NewMeter constructs and registers a new StandardMeter and launches a
4850// goroutine.
51+ // Be sure to unregister the meter from the registry once it is of no use to
52+ // allow for garbage collection.
4953func NewRegisteredMeter (name string , r Registry ) Meter {
5054 c := NewMeter ()
5155 if nil == r {
@@ -125,7 +129,6 @@ type StandardMeter struct {
125129 a1 , a5 , a15 EWMA
126130 startTime time.Time
127131 stopped bool
128- id int64
129132}
130133
131134func newStandardMeter () * StandardMeter {
@@ -138,15 +141,15 @@ func newStandardMeter() *StandardMeter {
138141 }
139142}
140143
141- // Stop stops the meter, Mark() will panic if you use it after being stopped.
144+ // Stop stops the meter, Mark() will be a no-op if you use it after being stopped.
142145func (m * StandardMeter ) Stop () {
143146 m .lock .Lock ()
144147 stopped := m .stopped
145148 m .stopped = true
146149 m .lock .Unlock ()
147150 if ! stopped {
148151 arbiter .Lock ()
149- delete (arbiter .meters , m . id )
152+ delete (arbiter .meters , m )
150153 arbiter .Unlock ()
151154 }
152155}
@@ -231,15 +234,16 @@ func (m *StandardMeter) tick() {
231234 m .updateSnapshot ()
232235}
233236
237+ // meterArbiter ticks meters every 5s from a single goroutine.
238+ // meters are references in a set for future stopping.
234239type meterArbiter struct {
235240 sync.RWMutex
236241 started bool
237- meters map [int64 ] * StandardMeter
242+ meters map [* StandardMeter ] struct {}
238243 ticker * time.Ticker
239- id int64
240244}
241245
242- var arbiter = meterArbiter {ticker : time .NewTicker (5e9 ), meters : make (map [int64 ] * StandardMeter )}
246+ var arbiter = meterArbiter {ticker : time .NewTicker (5e9 ), meters : make (map [* StandardMeter ] struct {} )}
243247
244248// Ticks meters on the scheduled interval
245249func (ma * meterArbiter ) tick () {
@@ -251,16 +255,10 @@ func (ma *meterArbiter) tick() {
251255 }
252256}
253257
254- // should only be called with Lock() held
255- func (ma * meterArbiter ) newID () int64 {
256- ma .id ++
257- return ma .id
258- }
259-
260258func (ma * meterArbiter ) tickMeters () {
261259 ma .RLock ()
262260 defer ma .RUnlock ()
263- for _ , meter := range ma .meters {
261+ for meter := range ma .meters {
264262 meter .tick ()
265263 }
266264}
0 commit comments