use stopc instead of stopped

master
hzsunshx 9 years ago
parent 9a2b190955
commit e381e923db

@ -194,7 +194,15 @@ func grpcDial(network, addr string) (*grpc.ClientConn, error) {
})) }))
} }
func ShutdownAction(ctx *cli.Context, client pb.GoSuvClient) { func ShutdownAction(ctx *cli.Context) {
conn, err := connect(ctx)
if err != nil {
fmt.Println("server already closed")
return
}
defer conn.Close()
client := pb.NewGoSuvClient(conn)
res, err := client.Shutdown(context.Background(), &pb.NopRequest{}) res, err := client.Shutdown(context.Background(), &pb.NopRequest{})
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -273,7 +281,7 @@ func initCli() {
{ {
Name: "shutdown", Name: "shutdown",
Usage: "Shutdown server", Usage: "Shutdown server",
Action: wrap(ShutdownAction), Action: ShutdownAction,
}, },
{ {
Name: "serv", Name: "serv",

@ -78,8 +78,8 @@ type Program struct {
Sig chan os.Signal `json:"-"` Sig chan os.Signal `json:"-"`
Info *ProgramInfo `json:"info"` Info *ProgramInfo `json:"info"`
retry int retry int
stopped bool stopc chan bool
} }
func NewProgram(info *ProgramInfo) *Program { func NewProgram(info *ProgramInfo) *Program {
@ -92,6 +92,7 @@ func NewProgram(info *ProgramInfo) *Program {
Status: ST_STANDBY, Status: ST_STANDBY,
Sig: make(chan os.Signal), Sig: make(chan os.Signal),
Info: info, Info: info,
stopc: make(chan bool),
} }
} }
@ -121,51 +122,57 @@ func (p *Program) createLog() (*os.File, error) {
} }
func (p *Program) sleep(d time.Duration) { func (p *Program) sleep(d time.Duration) {
// FIXME(ssx): when signal comes, finished sleep select {
time.Sleep(d) case <-p.stopc:
return
case <-time.After(time.Second * 2):
}
} }
func (p *Program) RunWithRetry() { func (p *Program) RunWithRetry() {
p.stopped = false
for p.retry = 0; p.retry < p.Info.StartRetries; p.retry += 1 { for p.retry = 0; p.retry < p.Info.StartRetries; p.retry += 1 {
p.Run() // wait program to exit
if p.stopped { select {
p.setStatus(ST_STOPPED) case err := <-GoFunc(p.Run):
log.Info(p.Info.Name, err)
case <-p.stopc:
return return
} }
// retry
if p.retry+1 < p.Info.StartRetries { if p.retry+1 < p.Info.StartRetries {
p.setStatus(ST_RETRYWAIT) p.setStatus(ST_RETRYWAIT)
p.sleep(time.Second * 2) // RETRYWAIT select {
case <-p.stopc:
return
case <-time.After(time.Second * 2):
}
} }
} }
p.setStatus(ST_FATAL) p.setStatus(ST_FATAL)
} }
func (p *Program) Run() (err error) { func (p *Program) Run() (err error) {
if err := p.Start(); err != nil { if err = p.Start(); err != nil {
log.Println("start:", err) return
p.setStatus(ST_FATAL)
return err
} }
p.setStatus(ST_RUNNING) p.setStatus(ST_RUNNING)
defer func() { defer func() {
if out, ok := p.Cmd.Stdout.(io.Closer); ok { if out, ok := p.Cmd.Stdout.(io.Closer); ok {
out.Close() out.Close()
} }
if !p.stopped && err != nil { log.Warnf("program finish: %v", err)
log.Warnf("program finish: %v", err)
p.setStatus(ST_FATAL)
} else {
p.setStatus(ST_STOPPED)
}
}() }()
err = p.Wait() err = p.Wait()
return return
} }
func (p *Program) Stop() error { func (p *Program) Stop() error {
p.stopped = true select {
case p.stopc <- true: // stopc may not recevied
case <-time.After(time.Millisecond * 50):
}
p.Terminate(syscall.SIGKILL) p.Terminate(syscall.SIGKILL)
p.setStatus(ST_STOPPED)
return nil return nil
} }

@ -70,7 +70,7 @@ func (s *PbSuvServer) Status(ctx context.Context, in *pb.NopRequest) (res *pb.St
ps := &pb.ProgramStatus{} ps := &pb.ProgramStatus{}
ps.Name = proto.String(program.Info.Name) ps.Name = proto.String(program.Info.Name)
ps.Status = proto.String(program.Status) ps.Status = proto.String(program.Status)
ps.Extra = proto.String("nothing") ps.Extra = proto.String("...")
res.Programs = append(res.Programs, ps) res.Programs = append(res.Programs, ps)
} }
return return

Loading…
Cancel
Save