-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathtarget.go
74 lines (65 loc) · 1.38 KB
/
target.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
package monitor
import (
"net"
"sync"
"time"
ping "github.com/digineo/go-ping"
)
// Target is a unit of work
type Target struct {
pinger *ping.Pinger
addr net.IPAddr
interval time.Duration
timeout time.Duration
stop chan struct{}
history History
wg sync.WaitGroup
}
// newTarget starts a new monitoring goroutine
func newTarget(interval, timeout, startupDelay time.Duration, historySize int, pinger *ping.Pinger, addr net.IPAddr) (*Target, error) {
n := &Target{
pinger: pinger,
addr: addr,
interval: interval,
timeout: timeout,
stop: make(chan struct{}),
history: NewHistory(historySize),
}
n.wg.Add(1)
go n.run(startupDelay)
return n, nil
}
func (n *Target) run(startupDelay time.Duration) {
if startupDelay > 0 {
select {
case <-time.After(startupDelay):
case <-n.stop:
}
}
tick := time.NewTicker(n.interval)
for {
select {
case <-n.stop:
tick.Stop()
n.wg.Done()
return
case <-tick.C:
go n.ping()
}
}
}
// Stop gracefully stops the monitoring.
func (n *Target) Stop() {
close(n.stop)
n.wg.Wait()
}
// Compute returns the computed ping metrics for this node and optonally clears the result set.
func (n *Target) Compute(clear bool) *Metrics {
if clear {
return n.history.ComputeAndClear()
}
return n.history.Compute()
}
func (n *Target) ping() {
n.history.AddResult(n.pinger.Ping(&n.addr, n.timeout))
}