Merge pull request #29 from c0b/resolve-zombies-in-container

loop reaping dead children
master
shengxiang 7 years ago
commit afdb6fe37e

@ -67,11 +67,16 @@ After you installed gosuv, the first thing is to start server.
gosuv start-server gosuv start-server
``` ```
Show server status Basic operations
```sh ```sh
$ gosuv status $ gosuv status
Server is running PROGRAM NAME STATUS
test running
test_again stopped
$ gosuv stop test
$ gosuv start test
``` ```
Open web <http://localhost:11313> to see the manager page. And follow the gif to add a program to gosuv. Open web <http://localhost:11313> to see the manager page. And follow the gif to add a program to gosuv.

@ -14,6 +14,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/franela/goreq"
"github.com/goji/httpauth" "github.com/goji/httpauth"
"github.com/urfave/cli" "github.com/urfave/cli"
) )
@ -83,11 +84,68 @@ func actionStartServer(c *cli.Context) error {
} }
func actionStatus(c *cli.Context) error { func actionStatus(c *cli.Context) error {
err := checkServerStatus() res, err := goreq.Request{
Uri: cfg.Client.ServerURL + "/api/programs",
}.Do()
if err != nil { if err != nil {
log.Fatal(err) return err
}
var programs = make([]struct {
Program Program `json:"program"`
Status string `json:"status"`
}, 0)
if err := res.Body.FromJsonTo(&programs); err != nil {
return err
}
format := "%-23s\t%-8s\n"
fmt.Printf(format, "PROGRAM NAME", "STATUS")
for _, p := range programs {
fmt.Printf(format, p.Program.Name, p.Status)
}
return nil
}
// cmd: <start|stop>
func programOperate(cmd, name string) (err error, success bool) {
res, err := goreq.Request{
Method: "POST",
Uri: cfg.Client.ServerURL + "/api/programs/" + name + "/" + cmd,
}.Do()
if err != nil {
return
}
var v = struct {
Status int `json:"status"`
}{}
if err = res.Body.FromJsonTo(&v); err != nil {
return
}
success = v.Status == 0
return
}
func actionStart(c *cli.Context) (err error) {
name := c.Args().First()
err, success := programOperate("start", name)
if err != nil {
return
}
if success {
fmt.Println("Started")
} else { } else {
log.Println("Server is running, OK.") fmt.Println("Start failed")
}
return nil
}
func actionStop(c *cli.Context) (err error) {
name := c.Args().First()
err, success := programOperate("stop", name)
if err != nil {
return
}
if !success {
fmt.Println("Stop failed")
} }
return nil return nil
} }

@ -141,6 +141,16 @@ func main() {
Usage: "Show program status", Usage: "Show program status",
Action: actionStatus, Action: actionStatus,
}, },
{
Name: "start",
Usage: "Start program",
Action: actionStart,
},
{
Name: "stop",
Usage: "Stop program",
Action: actionStop,
},
{ {
Name: "reload", Name: "reload",
Usage: "Reload config file", Usage: "Reload config file",

@ -3,6 +3,7 @@
package main package main
import ( import (
"log"
"os" "os"
"os/signal" "os/signal"
"syscall" "syscall"
@ -23,6 +24,18 @@ func watchChildSignal() {
} }
func reapChildren() { func reapChildren() {
var wstatus syscall.WaitStatus for {
syscall.Wait4(-1, &wstatus, syscall.WNOHANG, nil) var wstatus syscall.WaitStatus
wpid, err := syscall.Wait4(-1, &wstatus, syscall.WNOHANG, nil)
if err != nil {
log.Printf("syscall.Wait4 call failed: %v", err)
break
}
if wpid != 0 {
log.Printf("reap dead child: %d, wstatus: %#08x", wpid, wstatus)
} else {
break
}
}
} }

Loading…
Cancel
Save