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