diff --git a/README.md b/README.md index 814dcde..8a13d34 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # gocron - 定时任务web管理系统 # 项目简介 -使用Go语言开发的定时任务集中调度和管理系统, 用于替代Linux-crontab +使用Go语言开发的定时任务集中调度和管理系统, 用于替代Linux-crontab [查看文档](https://github.com/ouqiang/gocron/wiki) ## 功能特性 * 支持任务CURD diff --git a/cmd/web.go b/cmd/web.go index 57f53c5..ff48d4f 100644 --- a/cmd/web.go +++ b/cmd/web.go @@ -12,6 +12,7 @@ import ( "github.com/ouqiang/gocron/service" "github.com/ouqiang/gocron/models" "github.com/ouqiang/gocron/modules/setting" + "time" ) // web服务器默认端口 @@ -45,6 +46,7 @@ func run(ctx *cli.Context) { // 捕捉信号,配置热更新等 go catchSignal() m := macaron.Classic() + // 注册路由 routers.Register(m) // 注册中间件. @@ -110,7 +112,25 @@ func catchSignal() { logger.Info("收到信号 -- ", s) switch s { case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM: - os.Exit(1) + shutdown() } } +} + +func shutdown() { + logger.Info("应用准备退出\n停止任务调度") + serviceTask := new(service.Task) + // 停止所有任务调度 + serviceTask.StopAll() + taskNumInRunning := service.TaskNum.Num() + logger.Infof("正在运行的任务有%d个", taskNumInRunning) + for { + if taskNumInRunning <= 0 { + break + } + time.Sleep(3 * time.Second) + taskNumInRunning = service.TaskNum.Num() + } + logger.Info("已退出") + os.Exit(0) } \ No newline at end of file diff --git a/modules/logger/logger.go b/modules/logger/logger.go index eaf2f6c..04398b3 100644 --- a/modules/logger/logger.go +++ b/modules/logger/logger.go @@ -81,9 +81,11 @@ func write(level Level, v ...interface{}) { defer logger.Flush() content := "" - pc, file, line, ok := runtime.Caller(2) - if ok { - content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line) + if macaron.Env == macaron.DEV { + pc, file, line, ok := runtime.Caller(2) + if ok { + content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line) + } } switch level { @@ -105,9 +107,11 @@ func writef(level Level, format string, v ...interface{}) { defer logger.Flush() content := "" - pc, file, line, ok := runtime.Caller(2) - if ok { - content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line) + if macaron.Env == macaron.DEV { + pc, file, line, ok := runtime.Caller(2) + if ok { + content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line) + } } format = content + format diff --git a/service/task.go b/service/task.go index a05c0ef..1748e90 100644 --- a/service/task.go +++ b/service/task.go @@ -12,10 +12,40 @@ import ( "fmt" "github.com/ouqiang/gocron/modules/httpclient" "github.com/ouqiang/gocron/modules/notify" + "sync" ) +// 定时任务调度管理器 var Cron *cron.Cron +// 同一任务是否有实例处于运行中 var runInstance Instance +// 任务计数-正在运行中的任务 +var TaskNum TaskCount + +// 任务计数 +type TaskCount struct { + num int + sync.RWMutex +} + +func (c *TaskCount) Add() { + c.Lock() + defer c.Unlock() + c.num += 1 +} + +func (c *TaskCount) Done() { + c.Lock() + defer c.Unlock() + c.num -= 1 +} + +func (c *TaskCount) Num() int { + c.RLock() + defer c.RUnlock() + + return c.num +} // 任务ID作为Key, 不会出现并发写, 不加锁 type Instance struct { @@ -54,6 +84,8 @@ func (task *Task) Initialize() { Cron = cron.New() Cron.Start() runInstance = Instance{make(map[int]bool)} + TaskNum = TaskCount{0, sync.RWMutex{}} + taskModel := new(models.Task) taskList, err := taskModel.ActiveList() if err != nil { @@ -91,6 +123,11 @@ func (task *Task) Add(taskModel models.TaskHost) { } } +// 停止所有任务 +func (task *Task) StopAll() { + Cron.Stop() +} + // 直接运行任务 func (task *Task) Run(taskModel models.TaskHost) { go createJob(taskModel)() @@ -231,6 +268,8 @@ func createJob(taskModel models.TaskHost) cron.FuncJob { return nil } taskFunc := func() { + TaskNum.Add() + defer TaskNum.Done() taskLogId := beforeExecJob(&taskModel) if taskLogId <= 0 { return