Skip to content

Commit 7cc551e

Browse files
authored
fix: prevent race condition in Stop method on gauge (#342)
1 parent 55b1d8e commit 7cc551e

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

metriks/gauge.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package metriks
22

33
import (
44
"context"
5-
"sync"
65
"sync/atomic"
76
"time"
87

@@ -24,7 +23,7 @@ type PersistentGauge struct {
2423
ticker *time.Ticker
2524
cancel context.CancelFunc
2625
dur time.Duration
27-
wg sync.WaitGroup
26+
donec chan struct{}
2827
}
2928

3029
// Set will replace the value with a new one, it returns the old value
@@ -48,11 +47,10 @@ func (g *PersistentGauge) report(v int32) {
4847
}
4948

5049
func (g *PersistentGauge) start(ctx context.Context) {
51-
g.wg.Add(1)
5250
for {
5351
select {
5452
case <-ctx.Done():
55-
g.wg.Done()
53+
close(g.donec)
5654
return
5755
case <-g.ticker.C:
5856
g.report(atomic.LoadInt32(&g.value))
@@ -64,7 +62,7 @@ func (g *PersistentGauge) start(ctx context.Context) {
6462
// to the metrics collector
6563
func (g *PersistentGauge) Stop() {
6664
g.cancel()
67-
g.wg.Wait()
65+
<-g.donec
6866
}
6967

7068
// NewPersistentGauge will create and start a PersistentGauge that reports the current value every 10s
@@ -81,6 +79,7 @@ func NewPersistentGaugeWithDuration(name string, dur time.Duration, tags ...metr
8179
ticker: time.NewTicker(dur),
8280
cancel: cancel,
8381
dur: dur,
82+
donec: make(chan struct{}),
8483
}
8584
go g.start(ctx)
8685
return &g

metriks/gauge_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ func TestPersistentGauge(t *testing.T) {
3737
}
3838
}
3939

40+
func TestPersistentGaugeRace(t *testing.T) {
41+
for n := 0; n < 10; n++ {
42+
g := NewPersistentGaugeWithDuration("some_gauge", time.Second, L("a", "b"))
43+
g.Stop()
44+
}
45+
}
46+
4047
func TestScheduledGauge(t *testing.T) {
4148
var callCount int32
4249
cb := func() int32 {

0 commit comments

Comments
 (0)