Browse Source

update: daemon logical

v1.x.x
dnomd343 2 years ago
parent
commit
7570589308
  1. 52
      src/main.go
  2. 83
      src/process.go

52
src/main.go

@ -1,16 +1,12 @@
package main package main
import ( import (
"fmt"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"os"
"os/signal"
"syscall" "syscall"
"time"
) )
var xray *Process
var sleep *Process
var empty *Process
var logLevel = "warning" var logLevel = "warning"
var v4RouteTable = 100 var v4RouteTable = 100
@ -26,43 +22,35 @@ var addOnInbounds []interface{}
var assetFile = "/etc/xproxy/assets.tar.xz" var assetFile = "/etc/xproxy/assets.tar.xz"
func exit() {
log.Warningf("Start exit process")
xray.disableProcess()
xray.sendSignal(syscall.SIGTERM)
//log.Infof("Send kill signal to process %s", xray.caption)
sleep.disableProcess()
sleep.sendSignal(syscall.SIGTERM)
empty.disableProcess()
empty.sendSignal(syscall.SIGTERM)
log.Info("Wait sub process exit")
for !(xray.done && sleep.done) {
}
log.Infof("Exit complete")
}
func main() { func main() {
defer func() {
if err := recover(); err != nil {
log.Errorf("Unknown error -> %v", err)
}
}()
log.SetLevel(log.DebugLevel) log.SetLevel(log.DebugLevel)
log.Warning("XProxy start") log.Warning("XProxy start")
xray = newProcess("xray", "-confdir", "/etc/xproxy/config") xray := newProcess("xray", "-confdir", "/etc/xproxy/config")
xray.startProcess(true, true) xray.startProcess(true, true)
sleep = newProcess("sleep", "1000") sleep := newProcess("sleep", "1000")
sleep.startProcess(true, true) sleep.startProcess(true, true)
//done := make(chan bool, 1) empty := newProcess("empty")
daemon(xray) subProcess = append(subProcess, xray)
daemon(sleep) subProcess = append(subProcess, sleep)
daemon(empty) subProcess = append(subProcess, empty)
fmt.Println("start sleep...") for _, sub := range subProcess {
time.Sleep(10 * time.Second) daemon(sub)
fmt.Println("wake up") }
exit()
//<-done sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
<-sigs
exit()
//content, err := os.ReadFile("test.yml") //content, err := os.ReadFile("test.yml")
//if err != nil { //if err != nil {

83
src/process.go

@ -5,22 +5,24 @@ import (
"os" "os"
"os/exec" "os/exec"
"syscall" "syscall"
"time"
) )
var subProcess []*Process
type Process struct { type Process struct {
done bool
enable bool enable bool
caption 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 {
process := new(Process) process := new(Process)
process.enable = true process.name = command[0]
process.command = command process.command = command
process.caption = command[0] log.Debugf("New process %s -> %v", process.name, process.command)
log.Debugf("New process %s -> %v", process.caption, process.command)
return process return process
} }
@ -32,57 +34,78 @@ 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.caption, err) log.Errorf("Failed to start %s -> %v", p.name, err)
} }
log.Infof("Start process %s -> PID = %d", p.caption, p.process.Process.Pid) log.Infof("Start process %s -> PID = %d", p.name, p.process.Process.Pid)
}
func (p *Process) isProcessAlive() bool {
return p.process.ProcessState == nil
} }
func (p *Process) sendSignal(signal syscall.Signal) { func (p *Process) sendSignal(signal syscall.Signal) {
if p != nil { //defer func() {
err := p.process.Process.Signal(signal) // _ = recover()
if err != nil { //}()
log.Errorf("Send signal %v to process %s error -> %v", signal, p.caption, err) if p.process != nil && p.process.ProcessState == nil {
} log.Debugf("Send signal %v to %s", signal, p.name)
_ = p.process.Process.Signal(signal)
} }
} }
func (p *Process) waitProcess() { func (p *Process) waitProcess() {
if p.process != nil {
err := p.process.Wait() err := p.process.Wait()
if err != nil { if err != nil {
log.Warningf("Wait process %s -> %v", p.caption, err) log.Warningf("Wait process %s -> %v", p.name, err)
} }
}
func (p *Process) disableProcess() {
if p != nil {
p.enable = false
} }
} }
func daemonSub(sub *Process) { func daemonSub(sub *Process) {
for sub.isProcessAlive() { for sub.process.ProcessState == nil {
sub.waitProcess() sub.waitProcess()
} }
log.Warningf("Catch process %s exit", sub.caption) log.Warningf("Catch process %s exit", sub.name)
if sub.enable { if !sub.enable {
log.Debugf("Process %s disabled -> stop daemon", sub.name)
return
}
sub.startProcess(true, true) sub.startProcess(true, true)
log.Infof("Process %s restart success", xray.caption) log.Infof("Process %s restart success", sub.name)
daemonSub(sub) daemonSub(sub)
}
} }
func daemon(sub *Process) { func daemon(sub *Process) {
if sub != nil && sub.enable { if !sub.enable {
log.Infof("Start daemon of process %s", sub.caption) log.Infof("Process %s disabled -> skip daemon", sub.name)
sub.exit = true
return
}
log.Infof("Start daemon of process %s", sub.name)
go func() { go func() {
daemonSub(sub) daemonSub(sub)
sub.done = true log.Infof("Process %s daemon exit", sub.name)
sub.exit = true
}() }()
}
func exit() {
log.Warningf("Start exit process")
for _, sub := range subProcess {
sub.enable = false
if sub.process != nil {
sub.sendSignal(syscall.SIGTERM)
log.Infof("Send kill signal to process %s", sub.name)
}
}
var allExit bool
log.Info("Wait all sub process exit")
for !allExit {
time.Sleep(10 * time.Millisecond) // delay 10ms
allExit = true
for _, sub := range subProcess {
allExit = allExit && sub.exit //(sub.process.ProcessState != nil)
}
} }
log.Infof("Exit complete")
} }

Loading…
Cancel
Save