|
@ -8,14 +8,13 @@ import ( |
|
|
"time" |
|
|
"time" |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
var exitFlag bool |
|
|
var subProcess []*Process |
|
|
var subProcess []*Process |
|
|
|
|
|
|
|
|
type Process struct { |
|
|
type Process struct { |
|
|
enable bool |
|
|
|
|
|
name string |
|
|
name string |
|
|
command []string |
|
|
command []string |
|
|
process *exec.Cmd |
|
|
process *exec.Cmd |
|
|
exit bool |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func newProcess(command ...string) *Process { |
|
|
func newProcess(command ...string) *Process { |
|
@ -34,7 +33,6 @@ func (p *Process) startProcess(isStdout bool, isStderr bool) { |
|
|
if isStderr { |
|
|
if isStderr { |
|
|
p.process.Stderr = os.Stderr |
|
|
p.process.Stderr = os.Stderr |
|
|
} |
|
|
} |
|
|
p.enable = true |
|
|
|
|
|
err := p.process.Start() |
|
|
err := p.process.Start() |
|
|
if err != nil { |
|
|
if err != nil { |
|
|
log.Errorf("Failed to start %s -> %v", p.name, err) |
|
|
log.Errorf("Failed to start %s -> %v", p.name, err) |
|
@ -43,10 +41,7 @@ func (p *Process) startProcess(isStdout bool, isStderr bool) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func (p *Process) sendSignal(signal syscall.Signal) { |
|
|
func (p *Process) sendSignal(signal syscall.Signal) { |
|
|
//defer func() {
|
|
|
if p.process != nil { |
|
|
// _ = recover()
|
|
|
|
|
|
//}()
|
|
|
|
|
|
if p.process != nil && p.process.ProcessState == nil { |
|
|
|
|
|
log.Debugf("Send signal %v to %s", signal, p.name) |
|
|
log.Debugf("Send signal %v to %s", signal, p.name) |
|
|
_ = p.process.Process.Signal(signal) |
|
|
_ = p.process.Process.Signal(signal) |
|
|
} |
|
|
} |
|
@ -66,46 +61,55 @@ func daemonSub(sub *Process) { |
|
|
sub.waitProcess() |
|
|
sub.waitProcess() |
|
|
} |
|
|
} |
|
|
log.Warningf("Catch process %s exit", sub.name) |
|
|
log.Warningf("Catch process %s exit", sub.name) |
|
|
if !sub.enable { |
|
|
time.Sleep(10 * time.Millisecond) // delay 10ms
|
|
|
log.Debugf("Process %s disabled -> stop daemon", sub.name) |
|
|
if !exitFlag { |
|
|
return |
|
|
sub.startProcess(true, true) |
|
|
|
|
|
log.Infof("Process %s restart success", sub.name) |
|
|
|
|
|
daemonSub(sub) |
|
|
} |
|
|
} |
|
|
sub.startProcess(true, true) |
|
|
|
|
|
log.Infof("Process %s restart success", sub.name) |
|
|
|
|
|
daemonSub(sub) |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func daemon(sub *Process) { |
|
|
func daemon() { |
|
|
if !sub.enable { |
|
|
for _, sub := range subProcess { |
|
|
log.Infof("Process %s disabled -> skip daemon", sub.name) |
|
|
if sub.process == nil { |
|
|
sub.exit = true |
|
|
log.Infof("Process %s disabled -> skip daemon", sub.name) |
|
|
return |
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
log.Infof("Start daemon of process %s", sub.name) |
|
|
|
|
|
sub := sub |
|
|
|
|
|
go func() { |
|
|
|
|
|
daemonSub(sub) |
|
|
|
|
|
log.Infof("Process %s daemon exit", sub.name) |
|
|
|
|
|
}() |
|
|
} |
|
|
} |
|
|
log.Infof("Start daemon of process %s", sub.name) |
|
|
} |
|
|
go func() { |
|
|
|
|
|
daemonSub(sub) |
|
|
func killSub(sub *Process) { |
|
|
log.Infof("Process %s daemon exit", sub.name) |
|
|
defer func() { |
|
|
sub.exit = true |
|
|
recover() |
|
|
|
|
|
}() |
|
|
|
|
|
log.Infof("Send kill signal to process %s", sub.name) |
|
|
|
|
|
sub.sendSignal(syscall.SIGTERM) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func waitSub(sub *exec.Cmd) { |
|
|
|
|
|
defer func() { |
|
|
|
|
|
recover() |
|
|
}() |
|
|
}() |
|
|
|
|
|
_ = sub.Wait() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
func exit() { |
|
|
func exit() { |
|
|
|
|
|
exitFlag = true |
|
|
log.Warningf("Start exit process") |
|
|
log.Warningf("Start exit process") |
|
|
for _, sub := range subProcess { |
|
|
for _, sub := range subProcess { |
|
|
sub.enable = false |
|
|
|
|
|
if sub.process != nil { |
|
|
if sub.process != nil { |
|
|
sub.sendSignal(syscall.SIGTERM) |
|
|
killSub(sub) |
|
|
log.Infof("Send kill signal to process %s", sub.name) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
var allExit bool |
|
|
|
|
|
log.Info("Wait all sub process exit") |
|
|
log.Info("Wait all sub process exit") |
|
|
for !allExit { |
|
|
for _, sub := range subProcess { |
|
|
time.Sleep(10 * time.Millisecond) // delay 10ms
|
|
|
waitSub(sub.process) |
|
|
allExit = true |
|
|
|
|
|
for _, sub := range subProcess { |
|
|
|
|
|
allExit = allExit && sub.exit //(sub.process.ProcessState != nil)
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
log.Infof("Exit complete") |
|
|
log.Infof("Exit complete") |
|
|
} |
|
|
} |
|
|