forked from DataDog/datadog-agent
/
runner.go
99 lines (87 loc) · 2.16 KB
/
runner.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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package checks
import (
"errors"
"time"
"github.com/StackVista/stackstate-agent/pkg/util/log"
)
// RunnerConfig implements config for runners that work with CheckWithRealTime
type RunnerConfig struct {
CheckInterval time.Duration
RtInterval time.Duration
ExitChan chan struct{}
RtIntervalChan chan time.Duration
RtEnabled func() bool
RunCheck func(options RunOptions)
}
type runnerWithRealTime struct {
RunnerConfig
ratio int
counter int
newTicker func(d time.Duration) *time.Ticker
stopTicker func(t *time.Ticker)
}
// NewRunnerWithRealTime creates a runner func for CheckWithRealTime
func NewRunnerWithRealTime(config RunnerConfig) (func(), error) {
_, err := getRtRatio(config.CheckInterval, config.RtInterval)
if err != nil {
return nil, err
}
r := &runnerWithRealTime{
RunnerConfig: config,
newTicker: time.NewTicker,
stopTicker: func(t *time.Ticker) {
t.Stop()
},
}
return r.run, nil
}
// run performs runs for CheckWithRealTime checks
func (r *runnerWithRealTime) run() {
var err error
r.ratio, err = getRtRatio(r.CheckInterval, r.RtInterval)
if err != nil {
return
}
ticker := r.newTicker(r.RtInterval)
for {
select {
case <-ticker.C:
if r.counter == r.ratio {
r.counter = 0
}
rtEnabled := r.RtEnabled()
if rtEnabled || r.counter == 0 {
r.RunCheck(RunOptions{
RunStandard: r.counter == 0,
RunRealTime: rtEnabled,
})
}
r.counter++
case d := <-r.RtIntervalChan:
// Live-update the ticker.
newRatio, err := getRtRatio(r.CheckInterval, d)
if err != nil {
log.Errorf("failed to apply new RT interval: %v", err)
continue
}
r.RtInterval = d
r.stopTicker(ticker)
ticker = r.newTicker(d)
r.ratio = newRatio
r.counter = 0
case _, ok := <-r.ExitChan:
if !ok {
return
}
}
}
}
func getRtRatio(checkInterval, rtInterval time.Duration) (int, error) {
if checkInterval < rtInterval {
return -1, errors.New("check interval should be larger or equal to RT interval")
}
if checkInterval%rtInterval != 0 {
return -1, errors.New("check interval should be divisible by RT interval")
}
return int(checkInterval / rtInterval), nil
}