goProject/trunk/center/common/timer/timer_handler.go

160 lines
3.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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++
}
}