@@ -10,7 +10,7 @@ type WithTimestamp interface {
10
10
}
11
11
12
12
type Sampler [T WithTimestamp ] struct {
13
- mu sync.RWMutex
13
+ mu sync.Mutex
14
14
minInterval time.Duration
15
15
maxSamples int
16
16
callback func (ts time.Time ) (T , error )
@@ -26,19 +26,15 @@ type Sub[T WithTimestamp] struct {
26
26
first time.Time
27
27
last time.Time
28
28
samples []T
29
- mu sync.RWMutex
30
29
err error
31
30
}
32
31
33
32
func (s * Sub [T ]) Close (captureLast bool ) ([]T , error ) {
34
33
s .sampler .mu .Lock ()
35
34
delete (s .sampler .subs , s )
36
- s .sampler .mu .Unlock ()
37
-
38
- s .mu .Lock ()
39
- defer s .mu .Unlock ()
40
35
41
36
if s .err != nil {
37
+ s .sampler .mu .Unlock ()
42
38
return nil , s .err
43
39
}
44
40
current := s .first
@@ -50,6 +46,7 @@ func (s *Sub[T]) Close(captureLast bool) ([]T, error) {
50
46
current = ts
51
47
}
52
48
}
49
+ s .sampler .mu .Unlock ()
53
50
54
51
if captureLast {
55
52
v , err := s .sampler .callback (time .Now ())
@@ -98,26 +95,26 @@ func (s *Sampler[T]) run() {
98
95
return
99
96
case <- ticker .C :
100
97
tm := time .Now ()
101
- s .mu .RLock ()
98
+ s .mu .Lock ()
102
99
active := make ([]* Sub [T ], 0 , len (s .subs ))
103
100
for ss := range s .subs {
104
- ss .mu .Lock ()
105
101
if tm .Sub (ss .last ) < ss .interval {
106
- ss .mu .Unlock ()
107
102
continue
108
103
}
109
104
ss .last = tm
110
- ss .mu .Unlock ()
111
105
active = append (active , ss )
112
106
}
113
- s .mu .RUnlock ()
107
+ s .mu .Unlock ()
114
108
ticker = time .NewTimer (s .minInterval )
115
109
if len (active ) == 0 {
116
110
continue
117
111
}
118
112
value , err := s .callback (tm )
113
+ s .mu .Lock ()
119
114
for _ , ss := range active {
120
- ss .mu .Lock ()
115
+ if _ , found := s .subs [ss ]; ! found {
116
+ continue // skip if Close() was called while the lock was released
117
+ }
121
118
if err != nil {
122
119
ss .err = err
123
120
} else {
@@ -128,8 +125,8 @@ func (s *Sampler[T]) run() {
128
125
if time .Duration (ss .interval )* time .Duration (s .maxSamples ) <= dur {
129
126
ss .interval *= 2
130
127
}
131
- ss .mu .Unlock ()
132
128
}
129
+ s .mu .Unlock ()
133
130
}
134
131
}
135
132
}
0 commit comments