mirror of https://github.com/ouqiang/gocron
应用优雅退出
parent
ebb5139a7b
commit
4c07b02706
|
@ -2,7 +2,7 @@
|
||||||
# gocron - 定时任务web管理系统
|
# gocron - 定时任务web管理系统
|
||||||
|
|
||||||
# 项目简介
|
# 项目简介
|
||||||
使用Go语言开发的定时任务集中调度和管理系统, 用于替代Linux-crontab
|
使用Go语言开发的定时任务集中调度和管理系统, 用于替代Linux-crontab [查看文档](https://github.com/ouqiang/gocron/wiki)
|
||||||
|
|
||||||
## 功能特性
|
## 功能特性
|
||||||
* 支持任务CURD
|
* 支持任务CURD
|
||||||
|
|
22
cmd/web.go
22
cmd/web.go
|
@ -12,6 +12,7 @@ import (
|
||||||
"github.com/ouqiang/gocron/service"
|
"github.com/ouqiang/gocron/service"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/setting"
|
"github.com/ouqiang/gocron/modules/setting"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// web服务器默认端口
|
// web服务器默认端口
|
||||||
|
@ -45,6 +46,7 @@ func run(ctx *cli.Context) {
|
||||||
// 捕捉信号,配置热更新等
|
// 捕捉信号,配置热更新等
|
||||||
go catchSignal()
|
go catchSignal()
|
||||||
m := macaron.Classic()
|
m := macaron.Classic()
|
||||||
|
|
||||||
// 注册路由
|
// 注册路由
|
||||||
routers.Register(m)
|
routers.Register(m)
|
||||||
// 注册中间件.
|
// 注册中间件.
|
||||||
|
@ -110,7 +112,25 @@ func catchSignal() {
|
||||||
logger.Info("收到信号 -- ", s)
|
logger.Info("收到信号 -- ", s)
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM:
|
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)
|
||||||
}
|
}
|
|
@ -81,9 +81,11 @@ func write(level Level, v ...interface{}) {
|
||||||
defer logger.Flush()
|
defer logger.Flush()
|
||||||
|
|
||||||
content := ""
|
content := ""
|
||||||
pc, file, line, ok := runtime.Caller(2)
|
if macaron.Env == macaron.DEV {
|
||||||
if ok {
|
pc, file, line, ok := runtime.Caller(2)
|
||||||
content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line)
|
if ok {
|
||||||
|
content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch level {
|
switch level {
|
||||||
|
@ -105,9 +107,11 @@ func writef(level Level, format string, v ...interface{}) {
|
||||||
defer logger.Flush()
|
defer logger.Flush()
|
||||||
|
|
||||||
content := ""
|
content := ""
|
||||||
pc, file, line, ok := runtime.Caller(2)
|
if macaron.Env == macaron.DEV {
|
||||||
if ok {
|
pc, file, line, ok := runtime.Caller(2)
|
||||||
content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line)
|
if ok {
|
||||||
|
content = fmt.Sprintf("#%s#%s#%d行#", file, runtime.FuncForPC(pc).Name(), line)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format = content + format
|
format = content + format
|
||||||
|
|
|
@ -12,10 +12,40 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ouqiang/gocron/modules/httpclient"
|
"github.com/ouqiang/gocron/modules/httpclient"
|
||||||
"github.com/ouqiang/gocron/modules/notify"
|
"github.com/ouqiang/gocron/modules/notify"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// 定时任务调度管理器
|
||||||
var Cron *cron.Cron
|
var Cron *cron.Cron
|
||||||
|
// 同一任务是否有实例处于运行中
|
||||||
var runInstance Instance
|
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, 不会出现并发写, 不加锁
|
// 任务ID作为Key, 不会出现并发写, 不加锁
|
||||||
type Instance struct {
|
type Instance struct {
|
||||||
|
@ -54,6 +84,8 @@ func (task *Task) Initialize() {
|
||||||
Cron = cron.New()
|
Cron = cron.New()
|
||||||
Cron.Start()
|
Cron.Start()
|
||||||
runInstance = Instance{make(map[int]bool)}
|
runInstance = Instance{make(map[int]bool)}
|
||||||
|
TaskNum = TaskCount{0, sync.RWMutex{}}
|
||||||
|
|
||||||
taskModel := new(models.Task)
|
taskModel := new(models.Task)
|
||||||
taskList, err := taskModel.ActiveList()
|
taskList, err := taskModel.ActiveList()
|
||||||
if err != nil {
|
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) {
|
func (task *Task) Run(taskModel models.TaskHost) {
|
||||||
go createJob(taskModel)()
|
go createJob(taskModel)()
|
||||||
|
@ -231,6 +268,8 @@ func createJob(taskModel models.TaskHost) cron.FuncJob {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
taskFunc := func() {
|
taskFunc := func() {
|
||||||
|
TaskNum.Add()
|
||||||
|
defer TaskNum.Done()
|
||||||
taskLogId := beforeExecJob(&taskModel)
|
taskLogId := beforeExecJob(&taskModel)
|
||||||
if taskLogId <= 0 {
|
if taskLogId <= 0 {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue