🌼 separate different logic on each OS for child process to watch if master process exits

pull/628/head
kiyon 2020-07-17 06:51:57 +08:00
parent ae2d4bda2c
commit 227c751abc
6 changed files with 54 additions and 34 deletions

View File

@ -47,15 +47,9 @@ func (app *App) prefork(addr string, tlsconfig ...*tls.Config) (err error) {
ln = tls.NewListener(ln, tlsconfig[0])
}
// kill child proc when master exits
go func() {
p, err := os.FindProcess(os.Getppid())
if err == nil {
_, _ = p.Wait()
} else {
os.Exit(1)
}
}()
// kill current child proc when master exits
go watchMaster()
// listen for incoming connections
return app.server.Serve(ln)
}

View File

@ -1,13 +0,0 @@
// +build !windows
package fiber
import (
"os/exec"
)
var dummyChildCmd = "go"
func dummyCmd() *exec.Cmd {
return exec.Command(dummyChildCmd, "version")
}

View File

@ -1,11 +0,0 @@
package fiber
import (
"os/exec"
)
var dummyChildCmd = "go"
func dummyCmd() *exec.Cmd {
return exec.Command("cmd", "/C", dummyChildCmd, "version")
}

View File

@ -42,7 +42,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) {
utils.AssertEqual(t, nil, app.prefork("127.0.0.1:", config))
}
func Test_App_Prefork_Main_Process(t *testing.T) {
func Test_App_Prefork_Master_Process(t *testing.T) {
testPreforkMaster = true
app := New()

28
prefork_utils.go Normal file
View File

@ -0,0 +1,28 @@
// +build !windows
package fiber
import (
"os"
"os/exec"
"time"
)
var (
dummyChildCmd = "go"
)
func dummyCmd() *exec.Cmd {
return exec.Command(dummyChildCmd, "version")
}
// watchMaster gets ppid regularly,
// if it is equal to 1 (init process ID),
// it indicates that the master process has exited
func watchMaster() {
for range time.NewTicker(time.Millisecond * 500).C {
if os.Getppid() == 1 {
os.Exit(1)
}
}
}

22
prefork_utils_windows.go Normal file
View File

@ -0,0 +1,22 @@
package fiber
import (
"os"
"os/exec"
)
var dummyChildCmd = "go"
func dummyCmd() *exec.Cmd {
return exec.Command("cmd", "/C", dummyChildCmd, "version")
}
// watchMaster finds parent process,
// and waits for it to exit
func watchMaster() {
p, err := os.FindProcess(os.Getppid())
if err == nil {
_, _ = p.Wait()
}
os.Exit(1)
}