package main import ( "encoding/json" "fmt" "net" "net/http" "os" "os/signal" "path/filepath" "syscall" "time" pb "github.com/codeskyblue/gosuv/gosuvpb" "github.com/lunny/tango" "github.com/qiniu/log" "google.golang.org/grpc" ) type JSONResponse struct { Code int `json:"code"` Message string `json:"message"` } func renderJSON(w http.ResponseWriter, v interface{}) { w.Header().Add("Content-Type", "json") json.NewEncoder(w).Encode(v) } func versionHandler(w http.ResponseWriter, r *http.Request) { renderJSON(w, &JSONResponse{ Code: 200, Message: GOSUV_VERSION, }) } func statusHandler(w http.ResponseWriter, r *http.Request) { prms := programTable.Programs() renderJSON(w, prms) } func addHandler(w http.ResponseWriter, r *http.Request) { pinfo := new(ProgramInfo) err := json.NewDecoder(r.Body).Decode(pinfo) if err != nil { http.Error(w, err.Error(), 502) return } log.Printf("add: %#v", pinfo) program := NewProgram(pinfo) if err = programTable.AddProgram(program); err != nil { http.Error(w, err.Error(), 503) return } program.InputData(EVENT_START) renderJSON(w, &JSONResponse{ Code: 200, Message: "program add success", }) } func shutdownHandler(w http.ResponseWriter, r *http.Request) { go func() { time.Sleep(50 * time.Millisecond) os.Exit(2) }() renderJSON(w, &JSONResponse{ Code: 200, Message: "not implement", }) } func handleSignal(lis net.Listener) { sigc := make(chan os.Signal, 2) signal.Notify(sigc, syscall.SIGINT, syscall.SIGHUP) go func() { for sig := range sigc { log.Println("Receive signal:", sig) if sig == syscall.SIGHUP { return // ignore } lis.Close() programTable.StopAll() os.Exit(0) return } }() } func ServeAddr(addr string) error { InitServer() t := tango.New() t.Group("/api", func(g *tango.Group) { g.Get("/version", versionHandler) g.Post("/shutdown", shutdownHandler) g.Post("/programs", addHandler) g.Get("/programs", statusHandler) }) go t.Run(addr) lis, err := net.Listen("unix", filepath.Join(GOSUV_HOME, "gosuv.sock")) if err != nil { log.Fatal(err) } handleSignal(lis) pbServ := &PbSuvServer{} pbProgram := &PbProgram{} grpcServ := grpc.NewServer() pb.RegisterGoSuvServer(grpcServ, pbServ) pb.RegisterProgramServer(grpcServ, pbProgram) pbServ.lis = lis grpcServ.Serve(lis) return fmt.Errorf("Address: %s has been used", addr) }