This repository was archived by the owner on Apr 1, 2025. It is now read-only.
File tree Expand file tree Collapse file tree 2 files changed +22
-6
lines changed Expand file tree Collapse file tree 2 files changed +22
-6
lines changed Original file line number Diff line number Diff line change @@ -43,7 +43,8 @@ func NewMeter() Meter {
4343 arbiter .meters [m ] = struct {}{}
4444 if ! arbiter .started {
4545 arbiter .started = true
46- go arbiter .tick ()
46+ arbiter .cancel = make (chan struct {})
47+ go arbiter .tick (arbiter .ticker , arbiter .cancel )
4748 }
4849 return m
4950}
@@ -146,8 +147,20 @@ func newStandardMeter() *StandardMeter {
146147func (m * StandardMeter ) Stop () {
147148 if atomic .CompareAndSwapUint32 (& m .stopped , 0 , 1 ) {
148149 arbiter .Lock ()
150+ defer arbiter .Unlock ()
151+
149152 delete (arbiter .meters , m )
150- arbiter .Unlock ()
153+
154+ if len (arbiter .meters ) > 0 {
155+ return
156+ }
157+
158+ // reset the arbiter to a newly intialized state, allows
159+ // background goroutine (arbiter.tick) to terminate cleanly.
160+ arbiter .ticker .Stop ()
161+ close (arbiter .cancel )
162+ arbiter .ticker = time .NewTicker (5e9 )
163+ arbiter .started = false
151164 }
152165}
153166
@@ -228,16 +241,19 @@ type meterArbiter struct {
228241 started bool
229242 meters map [* StandardMeter ]struct {}
230243 ticker * time.Ticker
244+ cancel chan struct {}
231245}
232246
233247var arbiter = meterArbiter {ticker : time .NewTicker (5e9 ), meters : make (map [* StandardMeter ]struct {})}
234248
235249// Ticks meters on the scheduled interval
236- func (ma * meterArbiter ) tick () {
250+ func (ma * meterArbiter ) tick (ticker * time. Ticker , cancel <- chan struct {} ) {
237251 for {
238252 select {
239- case <- ma . ticker .C :
253+ case <- ticker .C :
240254 ma .tickMeters ()
255+ case <- cancel :
256+ return
241257 }
242258 }
243259}
Original file line number Diff line number Diff line change @@ -34,7 +34,7 @@ func TestMeterConcurrency(t *testing.T) {
3434 }
3535 m := newStandardMeter ()
3636 ma .meters [m ] = struct {}{}
37- go ma .tick ()
37+ go ma .tick (ma . ticker , nil )
3838 wg := & sync.WaitGroup {}
3939 reps := 100
4040 for i := 0 ; i < reps ; i ++ {
@@ -67,7 +67,7 @@ func TestMeterDecay(t *testing.T) {
6767 }
6868 m := newStandardMeter ()
6969 ma .meters [m ] = struct {}{}
70- go ma .tick ()
70+ go ma .tick (ma . ticker , nil )
7171 m .Mark (1 )
7272 rateMean := m .RateMean ()
7373 time .Sleep (100 * time .Millisecond )
You can’t perform that action at this time.
0 commit comments