-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathservice.go
More file actions
136 lines (116 loc) · 2.16 KB
/
service.go
File metadata and controls
136 lines (116 loc) · 2.16 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package reload
import (
"fmt"
"net"
"os"
"os/exec"
"os/signal"
"strings"
"sync"
"syscall"
)
// S 服务
type s struct {
L net.Listener
reLoad uint // 初始化次数
canReLoad uint // 允许重启次数,0为不限制
SigHandle sigHandle
sigChan chan os.Signal
sigs []os.Signal
isRun bool
stopChan chan struct{}
sync.WaitGroup
sync.RWMutex
logger Logger
}
// Start 开始监听信号量
func (s *s) Start() {
s.Lock()
s.isRun = true
s.Unlock()
signal.Notify(
s.sigChan,
s.sigs...,
)
go func() {
var sig os.Signal
pid := syscall.Getpid()
for {
sig = <-s.sigChan
s.logger.Debug(pid, "Received SIG.", sig)
if _, ok := s.SigHandle[sig]; ok {
s.SigHandle[sig](s)
}
}
}()
<-s.stopChan
}
// CanReLoad 是否可以重启
func (s *s) CanReLoad() bool {
s.RLock()
defer s.RUnlock()
if s.canReLoad == 0 {
return true
} else if s.reLoad >= s.canReLoad {
return false
}
return true
}
// SetCanReLoad 设置可重启次数
func (s *s) SetCanReLoad(count uint) {
s.Lock()
defer s.Unlock()
s.canReLoad = count
}
// IsChild 是否子进程
func (s *s) IsChild() bool {
s.RLock()
defer s.RUnlock()
return s.reLoad > 0
}
// Shutdown 停止
func (s *s) Shutdown() {
s.Lock()
defer s.Unlock()
s.Wait()
s.stopChan <- struct{}{}
}
// Reload 重启
func (s *s) Reload() (err error) {
if !s.CanReLoad() {
return fmt.Errorf("forked count is %d More The %d ", s.reLoad, s.canReLoad)
}
s.Lock()
defer s.Unlock()
s.reLoad++
s.logger.Debug("Restart: forked Start....")
tl := s.L.(*net.TCPListener)
fl, _ := tl.File()
path := os.Args[0]
var args []string
if len(os.Args) > 1 {
for _, arg := range os.Args[1:] {
tag := strings.Split(arg, "=")
if tag[0] == "-reLoad" {
break
}
args = append(args, arg)
}
}
args = append(args, fmt.Sprintf("-reLoad=%d", s.reLoad))
s.logger.Debug(path, args)
cmd := exec.Command(path, args...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.ExtraFiles = []*os.File{fl}
err = cmd.Start()
if err != nil {
s.logger.Error("Restart: Failed to launch, error: %v", err)
return
}
return
}
// Logger Logger
func (s *s) Logger() Logger {
return s.logger
}