This repository has been archived by the owner on Mar 3, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 52
/
pool.go
105 lines (87 loc) · 2.64 KB
/
pool.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
100
101
102
103
104
105
package pingd
import (
"log"
"time"
)
// HostStatus is a wrap around a host (name or IP), the host status
// represented by Down, and the reason why it's down. The status is
// used as initial state when monitoring starts and a event
// information when a host goes up or down.
type HostStatus struct {
Host string
Down bool
Reason error
}
// Receiver is a functions which takes 2 channels of Host
// in the first ones inserts Host(s) that should be monitored
// in the second one Host(s) that should stop being monitored
type Receiver func(chan<- HostStatus, chan<- HostStatus)
// Notifier is a function which takes 1 channel of Host(s)
// where it all hosts that went throw an UP or DOWN status change.
type Notifier func(<-chan HostStatus)
// Loader is a function which takes 1 channel of Host(s)
// where it should insert Host(s) that should be monitored
// this function will run at boot time to load an initial
// list of Host(s)
type Loader func(chan<- HostStatus)
// Pool is the structure that wraps the list of Host(s) that are
// being monitored, with the monitoring parameters and the functions
// interfacing with the rest of the system.
type Pool struct {
Ping PingFunc
Interval time.Duration
FailLimit int
Receive Receiver
Notify Notifier
Load Loader
list map[string]*Monitor
}
// Start create the necessary internal channels and
// calls all necessary functions to start the engine.
func (p *Pool) Start() {
p.list = make(map[string]*Monitor)
startHostCh := make(chan HostStatus, 10)
stopHostCh := make(chan HostStatus, 10)
notifyCh := make(chan HostStatus, 10)
if p.Load != nil {
go p.Load(startHostCh)
}
if p.Notify != nil {
go p.Notify(notifyCh)
}
if p.Receive != nil {
go p.Receive(startHostCh, stopHostCh)
}
go p.run(startHostCh, stopHostCh, notifyCh)
}
// run glues together the channels for communication with the host monitors
// and the rest of the system.
func (p *Pool) run(startHostCh, stopHostCh <-chan HostStatus, notifyCh chan<- HostStatus) {
for {
select {
// START
case h := <-startHostCh:
if _, exists := p.list[h.Host]; exists {
log.Println("RESTART pinging " + h.Host)
go func(h *Monitor) {
h.Stop()
h.Start(p.Interval, p.FailLimit)
}(p.list[h.Host])
} else {
log.Println("NEW host " + h.Host)
p.list[h.Host] = NewMonitor(h, p.Ping, notifyCh)
go func(h *Monitor) {
h.Start(p.Interval, p.FailLimit)
}(p.list[h.Host])
}
// STOP
case h := <-stopHostCh:
if _, exists := p.list[h.Host]; exists {
log.Println("STOP pinging " + h.Host)
p.list[h.Host].Stop()
} else {
log.Println("ERROR host not found " + h.Host)
}
}
}
}