-
Notifications
You must be signed in to change notification settings - Fork 0
/
worker.go
97 lines (86 loc) · 1.61 KB
/
worker.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
package master
import (
"os"
"os/signal"
"sync"
"syscall"
)
type worker struct {
waitGroup sync.WaitGroup
shutdown chan struct{}
lns []*Listener
events []func()
}
func newWorker(lns []*Listener) *worker {
w := &worker{
shutdown: make(chan struct{}),
lns: lns,
}
for _, ln := range w.lns {
ln.worker = w
}
if len(w.lns) > 0 {
w.waitGroup.Add(len(w.lns))
}
return w
}
func (w *worker) run() {
var (
once sync.Once
done = make(chan struct{})
sigHub = make(chan os.Signal)
sigExit = make(chan os.Signal)
)
signal.Notify(sigHub, syscall.SIGHUP)
signal.Notify(sigExit, syscall.SIGINT)
signal.Notify(sigExit, syscall.SIGTERM)
defer signal.Stop(sigHub)
defer signal.Stop(sigExit)
//优雅退出事件处理
go func() {
select {
case <-done:
case <-sigHub:
//关闭ln并等待conn关闭
w.closeAllListeners()
w.waitListenerAndConnectionClose()
once.Do(func() { close(done) })
}
}()
//强制退出事件处理
go func() {
select {
case <-done:
case <-sigExit:
w.closeAllListeners()
once.Do(func() { close(done) })
}
}()
<-done
//广播退出事件
for _, f := range w.events {
f()
}
close(w.shutdown)
}
func (w *worker) waitListenerAndConnectionClose() {
w.waitGroup.Wait()
for _, v := range w.lns {
v.wg.Wait()
}
}
func (w *worker) waitQuit() {
w.waitListenerAndConnectionClose()
<-w.shutdown
}
func (w *worker) registerExitEvent(event func()) {
w.events = append(w.events, event)
}
func (w *worker) listeners() []*Listener {
return w.lns
}
func (w *worker) closeAllListeners() {
for _, ln := range w.lns {
_ = ln.Close()
}
}