add basic web page

master
codeskyblue 8 years ago
parent f0ac31fdb1
commit 48f41b8ba1

@ -1,3 +1,17 @@
// 研究了一天的状态机,天气也热,正当我写的即将昏迷之际,我突然醒悟了,原来状态机是这么一回事
// - 状态比喻成 数据结构
// - 事件比喻成 用户输入
// - 状态转移则是函数调用
// 如此依赖写成函数,也就是 (Orz 原来如此)
// type FSM struct {
// State FSMState
// TransformFuncs map[FSMState] func()
// }
// func (f *FSM) UserAction(action FSMAction) {
// ...
// }
package main
import (
@ -81,13 +95,14 @@ type Program struct {
AutoStart bool `yaml:"autostart"` // change to *bool, which support unexpected
StartRetries int `yaml:"startretries"`
StartSeconds int `yaml:"startsecs"`
LogDir string `yaml:"logdir"`
// LogDir string `yaml:"logdir"`
}
type Process struct {
*FSM
Program
cmd *kexec.KCommand
stopC chan int
retryLeft int
}
@ -110,41 +125,45 @@ func (p *Process) waitNextRetry() {
select {
case <-time.After(2 * time.Second): // TODO: need put it into Program
go p.Operate(StartEvent)
case <-p.stopC:
p.stopCommand()
}
}
func (p *Process) waitExit() {
select {
case <-GoFunc(p.cmd.Wait):
func (p *Process) stopCommand() {
if p.cmd != nil {
p.cmd.Terminate(syscall.SIGKILL)
}
p.SetState(Stopped)
}
func NewProcess(pg Program) *Process {
pr := &Process{
FSM: NewFSM(Stopped),
Program: pg,
stopC: make(chan int),
retryLeft: pg.StartRetries,
}
startFunc := func() {
pr.SetState(Running)
pr.retryLeft = pr.StartRetries
pr.cmd = kexec.CommandString("echo hello world && sleep 10 && echo end")
pr.cmd.Stdout = os.Stdout
pr.SetState(Running)
go func() {
errC := GoFunc(pr.cmd.Run)
startTime := time.Now()
select {
case err := <-errC: //<-GoTimeoutFunc(time.Duration(pr.StartSeconds)*time.Second, pr.cmd.Run):
log.Println(err)
if time.Since(startTime) < time.Duration(pr.StartSeconds) {
pr.SetState(Fatal)
return
}
pr.waitNextRetry()
return
case <-time.After(time.Duration(pr.StartSeconds) * time.Second):
pr.retryLeft = pr.StartRetries // reset retries if success
}
// wait until exit
select {
case err := <-errC:
log.Println(err)
pr.waitNextRetry()
case <-pr.stopC:
pr.stopCommand()
}
}()
}
@ -154,8 +173,6 @@ func NewProcess(pg Program) *Process {
pr.AddHandler(Running, StopEvent, func() {
pr.cmd.Terminate(syscall.SIGKILL)
}).AddHandler(Stopped, RestartEvent, func() {
go pr.Operate(StartEvent)
}).AddHandler(Running, RestartEvent, func() {
go func() {
pr.Operate(StopEvent)
@ -168,20 +185,20 @@ func NewProcess(pg Program) *Process {
}
func init() {
pg := Program{
Name: "demo",
Command: "echo hello world && sleep 1 && echo end",
}
proc := NewProcess(pg)
log.Println(proc.State())
proc.Operate(RestartEvent)
log.Println(proc.State())
time.Sleep(2 * time.Second)
log.Println(proc.State())
proc.Operate(StopEvent)
time.Sleep(1 * time.Second)
log.Println(proc.State())
// pg := Program{
// Name: "demo",
// Command: "echo hello world && sleep 1 && echo end",
// }
// proc := NewProcess(pg)
// log.Println(proc.State())
// proc.Operate(StartEvent)
// log.Println(proc.State())
// time.Sleep(2 * time.Second)
// log.Println(proc.State())
// proc.Operate(StopEvent)
// time.Sleep(1 * time.Second)
// log.Println(proc.State())
// log.Println(light.State)
// light.AddHandler(Opened, Close, func() {
// log.Println("Close light")

@ -1,7 +1,49 @@
package main
import "log"
import (
"fmt"
"log"
"net/http"
"os"
"github.com/urfave/cli"
)
var (
GitSummary string = "unknown"
)
func actionServ(c *cli.Context) error {
fmt.Println("added serv: ", c.Args().First())
log.Fatal(http.ListenAndServe(":8000", nil))
return nil
}
func actionStatus(c *cli.Context) error {
log.Println("Status")
return nil
}
func main() {
log.Println("Started..")
app := cli.NewApp()
app.Name = "gosuv"
app.Version = GitSummary
app.Usage = "golang port of python-supervisor"
app.Commands = []cli.Command{
{
Name: "serv",
Usage: "Should only called by itself",
Action: actionServ,
},
{
Name: "status",
Aliases: []string{"st"},
Usage: "Show program status",
Action: actionStatus,
},
}
if err := app.Run(os.Args); err != nil {
os.Exit(1)
}
}

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html>
<head>
<title>gosuv</title>
</head>
<body>
<h1>Hello</h1>
</body>
</html>

@ -0,0 +1,34 @@
package main
import (
"encoding/json"
"html/template"
"net/http"
"github.com/gorilla/mux"
)
type Supervisor struct {
ConfigDir string
}
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)
}
func (s *Supervisor) AddProgram(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
data, _ := json.Marshal(map[string]interface{}{
"status": 0,
})
w.Write(data)
}
func init() {
suv := &Supervisor{}
r := mux.NewRouter()
r.HandleFunc("/", suv.Index)
r.HandleFunc("/api/programs", suv.AddProgram).Methods("POST")
http.Handle("/", r)
}
Loading…
Cancel
Save