gocron/cmd/web.go

170 lines
4.0 KiB
Go
Raw Normal View History

2017-03-10 09:24:06 +00:00
package cmd
import (
2017-04-02 02:38:49 +00:00
"github.com/go-macaron/csrf"
"github.com/go-macaron/gzip"
"github.com/go-macaron/session"
2017-04-07 01:22:00 +00:00
"github.com/ouqiang/gocron/modules/app"
"github.com/ouqiang/gocron/routers"
2017-04-02 02:38:49 +00:00
"github.com/urfave/cli"
"gopkg.in/macaron.v1"
"os"
"os/signal"
"path/filepath"
"os/exec"
"syscall"
2017-04-07 01:22:00 +00:00
"github.com/ouqiang/gocron/modules/logger"
2017-04-09 09:55:55 +00:00
"github.com/go-macaron/toolbox"
"strings"
2017-03-10 09:24:06 +00:00
)
2017-04-06 06:40:48 +00:00
// 1号进程id
const InitProcess = 1
2017-03-10 09:24:06 +00:00
// web服务器默认端口
const DefaultPort = 5920
2017-04-02 02:19:52 +00:00
2017-03-10 09:24:06 +00:00
// 静态文件目录
const StaticDir = "public"
var CmdWeb = cli.Command{
2017-04-02 02:38:49 +00:00
Name: "server",
Usage: "start scheduler web server",
Action: run,
Flags: []cli.Flag{
cli.IntFlag{
Name: "port,p",
Value: DefaultPort,
Usage: "bind port number",
},
2017-04-03 07:27:19 +00:00
cli.StringFlag{
Name: "env,e",
Value: "dev",
Usage: "runtime environment, dev|test|prod",
},
cli.StringFlag{
Name: "d",
Value: "false",
2017-04-06 06:58:34 +00:00
Usage: "-d=true, run app as daemon, not support windows",
},
2017-04-02 02:38:49 +00:00
},
2017-03-10 09:24:06 +00:00
}
func run(ctx *cli.Context) {
// 作为守护进程运行
becomeDaemon(ctx);
// 设置运行环境
2017-04-03 07:27:19 +00:00
setEnvironment(ctx)
// 初始化应用
2017-04-02 02:38:49 +00:00
app.InitEnv()
// 捕捉信号,配置热更新等
go catchSignal()
2017-04-02 02:38:49 +00:00
m := macaron.Classic()
// 注册路由
routers.Register(m)
// 注册中间件.
2017-04-02 02:38:49 +00:00
registerMiddleware(m)
port := parsePort(ctx)
m.Run(port)
2017-03-10 09:24:06 +00:00
}
// 中间件注册
2017-04-02 02:19:52 +00:00
func registerMiddleware(m *macaron.Macaron) {
2017-04-02 02:38:49 +00:00
m.Use(macaron.Logger())
m.Use(macaron.Recovery())
m.Use(gzip.Gziper())
m.Use(macaron.Static(StaticDir))
m.Use(macaron.Renderer(macaron.RenderOptions{
Directory: "templates",
Extensions: []string{".html"},
// 模板语法分隔符,默认为 ["{{", "}}"]
Delims: macaron.Delims{"{{{", "}}}"},
// 追加的 Content-Type 头信息,默认为 "UTF-8"
Charset: "UTF-8",
// 渲染具有缩进格式的 JSON默认为不缩进
IndentJSON: true,
// 渲染具有缩进格式的 XML默认为不缩进
IndentXML: true,
}))
m.Use(session.Sessioner())
m.Use(csrf.Csrfer())
2017-04-09 09:55:55 +00:00
m.Use(toolbox.Toolboxer(m))
// 系统未安装,重定向到安装页面
m.Use(func(ctx *macaron.Context) {
installUrl := "/install"
if strings.HasPrefix(ctx.Req.RequestURI, installUrl) {
return
}
if !app.Installed {
ctx.Redirect(installUrl)
}
})
2017-03-10 09:24:06 +00:00
}
// 解析端口
func parsePort(ctx *cli.Context) int {
2017-04-03 07:27:19 +00:00
var port int = DefaultPort
2017-04-02 02:38:49 +00:00
if ctx.IsSet("port") {
port = ctx.Int("port")
}
if port <= 0 || port >= 65535 {
port = DefaultPort
}
2017-03-10 09:24:06 +00:00
2017-04-02 02:38:49 +00:00
return port
2017-04-02 02:19:52 +00:00
}
2017-04-03 07:27:19 +00:00
func setEnvironment(ctx *cli.Context) {
var env string = ""
if ctx.IsSet("env") {
env = ctx.String("env")
}
if env == "prod" {
macaron.Env = macaron.PROD
}
}
// 捕捉信号
func catchSignal() {
c := make(chan os.Signal)
2017-04-06 06:40:48 +00:00
// todo 配置热更新, windows 不支持 syscall.SIGUSR1, syscall.SIGUSR2
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
2017-04-04 09:05:55 +00:00
for {
s := <- c
logger.Info("收到信号 -- ", s)
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM:
os.Exit(1)
}
}
}
func becomeDaemon(ctx *cli.Context) {
2017-04-06 06:58:34 +00:00
// 不支持windows
if app.IsWindows {
return
}
var daemond string = "false"
if ctx.IsSet("d") {
daemond = ctx.String("d")
}
if (daemond != "true") {
return
}
if os.Getppid() == InitProcess {
2017-04-06 06:40:48 +00:00
// 已是守护进程,不再处理
return
}
filePath, _:= filepath.Abs(os.Args[0])
cmd := exec.Command(filePath, os.Args[1:]...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Start()
// 父进程退出, 子进程由init-1号进程收养
os.Exit(0)
2017-04-03 07:27:19 +00:00
}