support reload

master
codeskyblue 8 years ago
parent 0e4302b134
commit 8fdfa6e9a1

@ -15,6 +15,8 @@
package main
import (
"errors"
"fmt"
"log"
"os"
"sync"
@ -98,6 +100,19 @@ type Program struct {
// LogDir string `yaml:"logdir"`
}
func (p *Program) Check() error {
if p.Name == "" {
return errors.New("Program name empty")
}
if p.Command == "" {
return errors.New("Program command empty")
}
if p.Dir != "" && !IsDir(p.Dir) {
return fmt.Errorf("Program dir(%s) not exists", p.Dir)
}
return nil
}
type Process struct {
*FSM
Program
@ -137,6 +152,10 @@ func (p *Process) stopCommand() {
p.SetState(Stopped)
}
func (p *Process) IsRunning() bool {
return p.State() == Running || p.State() == RetryWait
}
func NewProcess(pg Program) *Process {
pr := &Process{
FSM: NewFSM(Stopped),

@ -2,6 +2,7 @@ package main
import (
"errors"
"os"
"time"
"github.com/qiniu/log"
@ -31,3 +32,8 @@ func GoTimeoutFunc(timeout time.Duration, f func() error) chan error {
}()
return ch
}
func IsDir(dir string) bool {
fi, err := os.Stat(dir)
return err == nil && fi.IsDir()
}

@ -8,6 +8,7 @@ import (
"net/http"
"path/filepath"
"reflect"
"time"
"github.com/go-yaml/yaml"
"github.com/gorilla/mux"
@ -17,6 +18,7 @@ type Supervisor struct {
ConfigDir string
pgs []*Program
pgMap map[string]*Program
procMap map[string]*Process
}
func (s *Supervisor) programPath() string {
@ -28,10 +30,25 @@ func (s *Supervisor) addOrUpdateProgram(pg Program) {
if ok {
if !reflect.DeepEqual(origPg, &pg) {
log.Println("Update:", pg.Name)
origProc := s.procMap[pg.Name]
isRunning := origProc.IsRunning()
go func() {
origProc.Operate(StopEvent)
// TODO: wait state change
time.Sleep(2 * time.Second)
newProc := NewProcess(pg)
s.procMap[pg.Name] = newProc
if isRunning {
newProc.Operate(StartEvent)
}
}()
}
} else {
s.pgs = append(s.pgs, &pg)
s.pgMap[pg.Name] = &pg
s.procMap[pg.Name] = NewProcess(pg)
log.Println("Add:", pg.Name)
}
}
@ -51,6 +68,14 @@ func (s *Supervisor) loadDB() error {
return nil
}
func (s *Supervisor) saveDB() error {
data, err := yaml.Marshal(s.pgs)
if err != nil {
return err
}
return ioutil.WriteFile(s.programPath(), data, 0644)
}
func (s *Supervisor) Index(w http.ResponseWriter, r *http.Request) {
t := template.Must(template.New("t").ParseFiles("./res/index.html"))
t.ExecuteTemplate(w, "index.html", nil)
@ -60,9 +85,13 @@ func (s *Supervisor) AddProgram(w http.ResponseWriter, r *http.Request) {
pg := Program{
Name: r.FormValue("name"),
Command: r.FormValue("command"),
// TODO: missing other values
}
// TODO: need check pg
// pg.Check() error
if err := pg.Check(); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
w.Header().Set("Content-Type", "application/json")
var data []byte
if _, ok := s.pgMap[pg.Name]; ok {

Loading…
Cancel
Save