// AddProcWatcher will add a watcher on proc. func (watcher *Watcher) AddProcWatcher(proc process.ProcContainer) { watcher.Lock() defer watcher.Unlock() if _, ok := watcher.watchProcs[proc.Identifier()]; ok { log.Warnf("A watcher for this process already exists.") return } procWatcher := &ProcWatcher{ procStatus: make(chan *ProcStatus, 1), proc: proc, stopWatcher: make(chan bool, 1), } watcher.watchProcs[proc.Identifier()] = procWatcher go func() { log.Infof("Starting watcher on proc %s", proc.Identifier()) state, err := proc.Watch() procWatcher.procStatus <- &ProcStatus{ state: state, err: err, } }() go func() { defer delete(watcher.watchProcs, procWatcher.proc.Identifier()) select { case procStatus := <-procWatcher.procStatus: log.Infof("Proc %s is dead, advising master...", procWatcher.proc.Identifier()) log.Infof("State is %s", procStatus.state.String()) watcher.restartProc <- procWatcher.proc break case <-procWatcher.stopWatcher: break } }() }
func (master *Master) updateStatus(proc process.ProcContainer) { if proc.IsAlive() { proc.SetStatus("running") } else { proc.NotifyStopped() proc.SetStatus("stopped") } }
// NOT thread safe method. Lock should be acquire before calling it. func (master *Master) start(proc process.ProcContainer) error { if !proc.IsAlive() { err := proc.Start() if err != nil { return err } master.Watcher.AddProcWatcher(proc) proc.SetStatus("running") } return nil }
// NOT thread safe method. Lock should be acquire before calling it. func (master *Master) stop(proc process.ProcContainer) error { if proc.IsAlive() { waitStop := master.Watcher.StopWatcher(proc.Identifier()) err := proc.GracefullyStop() if err != nil { return err } if waitStop != nil { <-waitStop proc.NotifyStopped() proc.SetStatus("stopped") } log.Infof("Proc %s successfully stopped.", proc.Identifier()) } return nil }
func (master *Master) delete(proc process.ProcContainer) error { return proc.Delete() }