-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathhealthcheck.go
80 lines (74 loc) · 2.15 KB
/
healthcheck.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
package main
import (
"time"
)
type healthCheck struct {
device string
checker checker
interval Duration
intervalAF Duration
threshold int
healthy bool
running bool // bool to help us identify running healthchecks and stop them if needed
stop chan struct{} // Chan to signal hc to stop
renew chan struct{} // Chan to notify for a reboot
}
func newHealthCheck(device, address string, interval, intervalAF, timeout Duration, threshold int, renew chan struct{}) (*healthCheck, error) {
pc, err := newPingChecker(device, address, timeout)
if err != nil {
return &healthCheck{}, err
}
return &healthCheck{
device: device,
checker: pc,
interval: interval,
intervalAF: intervalAF,
threshold: threshold,
healthy: false, // assume target is not healthy when starting until we make a successful check
running: false,
stop: make(chan struct{}),
renew: renew,
}, nil
}
func (hc *healthCheck) Stop() {
if hc.running {
hc.stop <- struct{}{}
}
}
func (hc *healthCheck) Run() {
healthSyncTicker := time.NewTicker(hc.interval.Duration)
defer healthSyncTicker.Stop()
var unhealthyCount int
hc.running = true
for {
select {
case <-healthSyncTicker.C:
if err := hc.checker.Check(); err != nil {
unhealthyCount = unhealthyCount + 1
healthSyncTicker.Reset(hc.intervalAF.Duration)
logger.Errorf("healthcheck failed for peer %s@%s (%s)", hc.checker.TargetIP(), hc.device, err)
// if unhealthy count exceeds the threshold we need to stop the health check and look for a new lease
if unhealthyCount >= hc.threshold {
logger.Verbosef("server at: %s marked unhealthy, need to renew lease", hc.checker.TargetIP())
hc.running = false
hc.healthy = false
hc.renew <- struct{}{}
return
}
} else {
if !hc.healthy {
logger.Verbosef("server at: %s is healthy", hc.checker.TargetIP())
}
hc.healthy = true
if unhealthyCount > 0 {
unhealthyCount = 0
healthSyncTicker.Reset(hc.interval.Duration)
}
}
case <-hc.stop:
logger.Verbosef("stopping healthcheck for: %s", hc.checker.TargetIP())
hc.running = false
return
}
}
}