160 lines
3.9 KiB
Go
160 lines
3.9 KiB
Go
|
|
package timer
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"goutil/logUtilPlus"
|
|||
|
|
"time"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 触发类型
|
|||
|
|
const (
|
|||
|
|
// TriggerTypeMinute 一分钟
|
|||
|
|
TriggerTypeMinute = iota + 1
|
|||
|
|
// TriggerTypeFiveMinute 五分钟
|
|||
|
|
TriggerTypeFiveMinute
|
|||
|
|
// TriggerTypeTenMinute 十分钟
|
|||
|
|
TriggerTypeTenMinute
|
|||
|
|
// TriggerTypeHalfHour 半小时
|
|||
|
|
TriggerTypeHalfHour
|
|||
|
|
// TriggerTypeHour 一小时
|
|||
|
|
TriggerTypeHour
|
|||
|
|
// TriggerTypeEightHour 八小时
|
|||
|
|
TriggerTypeEightHour
|
|||
|
|
// TriggerTypeDay 一天 每天0点触发
|
|||
|
|
TriggerTypeDay
|
|||
|
|
// TriggerTypeWeek 一周 (周日0点触发)
|
|||
|
|
TriggerTypeWeek
|
|||
|
|
// TriggerTypeMonth 每月1号0点触发
|
|||
|
|
TriggerTypeMonth
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// TimerHandlerFunc 定义可执行的函数类型
|
|||
|
|
type timerHandlerFunc func(nowTime time.Time) error
|
|||
|
|
|
|||
|
|
// 时间触发管理
|
|||
|
|
var (
|
|||
|
|
timerHandlerMap = make(map[int][]timerHandlerFunc)
|
|||
|
|
timerTypeMap = map[int]struct{}{
|
|||
|
|
TriggerTypeMinute: {},
|
|||
|
|
TriggerTypeFiveMinute: {},
|
|||
|
|
TriggerTypeTenMinute: {},
|
|||
|
|
TriggerTypeHalfHour: {},
|
|||
|
|
TriggerTypeHour: {},
|
|||
|
|
TriggerTypeEightHour: {},
|
|||
|
|
TriggerTypeDay: {},
|
|||
|
|
TriggerTypeWeek: {},
|
|||
|
|
TriggerTypeMonth: {},
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// Register 注册时间触发器
|
|||
|
|
// @param timerType 时间触发类型
|
|||
|
|
// @param timerFunc 时间触发函数
|
|||
|
|
func Register(timerType int, timerFunc timerHandlerFunc) {
|
|||
|
|
|
|||
|
|
// 检查timerType是否在常量中
|
|||
|
|
if _, ok := timerTypeMap[timerType]; !ok {
|
|||
|
|
logUtilPlus.ErrorLog("注册时间触发器失败,类型不存在", "timerType", timerType)
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if _, ok := timerHandlerMap[timerType]; !ok {
|
|||
|
|
timerHandlerMap[timerType] = make([]timerHandlerFunc, 0)
|
|||
|
|
}
|
|||
|
|
timerHandlerMap[timerType] = append(timerHandlerMap[timerType], timerFunc)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Execute 执行时间触发器
|
|||
|
|
// @param timerType 时间触发类型
|
|||
|
|
// @param nowTime 当前时间
|
|||
|
|
func Execute(timerType int, nowTime time.Time) {
|
|||
|
|
if _, ok := timerHandlerMap[timerType]; !ok {
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
for _, timerHandlerFunc := range timerHandlerMap[timerType] {
|
|||
|
|
if err := timerHandlerFunc(nowTime); err != nil {
|
|||
|
|
logUtilPlus.ErrorLog("执行时间触发器失败", "timerType", timerType, "err", err)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 初始化init
|
|||
|
|
func init() {
|
|||
|
|
go timerHandler()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 定时触发函数
|
|||
|
|
func timerHandler() {
|
|||
|
|
|
|||
|
|
// 每一分钟执行一次
|
|||
|
|
ticker := time.NewTicker(time.Minute)
|
|||
|
|
defer ticker.Stop()
|
|||
|
|
defer func() {
|
|||
|
|
if err := recover(); err != nil {
|
|||
|
|
logUtilPlus.ErrorLog("定时触发函数异常", "err", err)
|
|||
|
|
restartTimerHandler()
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case nowTime := <-ticker.C:
|
|||
|
|
go func() {
|
|||
|
|
// 触发minute
|
|||
|
|
Execute(TriggerTypeMinute, nowTime)
|
|||
|
|
// 触发fiveMinute
|
|||
|
|
if nowTime.Minute()%5 == 0 {
|
|||
|
|
Execute(TriggerTypeFiveMinute, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发tenMinute
|
|||
|
|
if nowTime.Minute()%10 == 0 {
|
|||
|
|
Execute(TriggerTypeTenMinute, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发halfHour
|
|||
|
|
if nowTime.Minute()%30 == 0 {
|
|||
|
|
Execute(TriggerTypeHalfHour, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发hour
|
|||
|
|
if nowTime.Minute() == 0 {
|
|||
|
|
Execute(TriggerTypeHour, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发eightHour
|
|||
|
|
if nowTime.Hour()%8 == 0 {
|
|||
|
|
Execute(TriggerTypeEightHour, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发day 0点触发
|
|||
|
|
if nowTime.Hour() == 0 && nowTime.Minute() == 0 {
|
|||
|
|
Execute(TriggerTypeDay, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发week 周日0点触发
|
|||
|
|
if nowTime.Weekday() == time.Sunday && nowTime.Hour() == 0 && nowTime.Minute() == 0 {
|
|||
|
|
Execute(TriggerTypeWeek, nowTime)
|
|||
|
|
}
|
|||
|
|
// 触发month 1号0点触发
|
|||
|
|
if nowTime.Day() == 1 && nowTime.Hour() == 0 && nowTime.Minute() == 0 {
|
|||
|
|
Execute(TriggerTypeMonth, nowTime)
|
|||
|
|
}
|
|||
|
|
}()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// restartTimerHandler 重启定时器
|
|||
|
|
func restartTimerHandler() {
|
|||
|
|
// 设置重试次数
|
|||
|
|
maxRetries := 5
|
|||
|
|
retryCount := 0
|
|||
|
|
|
|||
|
|
for {
|
|||
|
|
select {
|
|||
|
|
case <-time.After(5 * time.Minute): // 等待5分钟后重试
|
|||
|
|
if retryCount >= maxRetries {
|
|||
|
|
logUtilPlus.ErrorLog("定时器重启失败,达到最大重试次数")
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
logUtilPlus.InfoLog("重新启动定时器,重试次数: %d", retryCount+1)
|
|||
|
|
go timerHandler()
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
retryCount++
|
|||
|
|
}
|
|||
|
|
}
|