/
sampler.go
62 lines (54 loc) · 1.09 KB
/
sampler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package monitor
import (
"context"
"sync"
"time"
)
type ConditionalSampler interface {
ConditionWhenFailing(*Condition) SamplerFunc
}
type sampler struct {
lock sync.Mutex
available bool
}
func StartSampling(ctx context.Context, recorder Recorder, interval time.Duration, sampleFn func(previous bool) (*Condition, bool)) ConditionalSampler {
s := &sampler{
available: true,
}
go func() {
ticker := time.NewTicker(interval)
defer ticker.Stop()
for {
select {
case <-ticker.C:
case <-ctx.Done():
return
}
success := s.isAvailable()
condition, ok := sampleFn(success)
if condition != nil {
recorder.Record(*condition)
}
s.setAvailable(ok)
}
}()
return s
}
func (s *sampler) isAvailable() bool {
s.lock.Lock()
defer s.lock.Unlock()
return s.available
}
func (s *sampler) setAvailable(b bool) {
s.lock.Lock()
defer s.lock.Unlock()
s.available = b
}
func (s *sampler) ConditionWhenFailing(condition *Condition) SamplerFunc {
return func(_ time.Time) []*Condition {
if s.isAvailable() {
return nil
}
return []*Condition{condition}
}
}