package myth import ( "container/list" "context" "log" "time" ) // TaskFunc 任务执行函数 type TaskFunc func(string, time.Time) // 任务主体 type Task struct { Seconds int64 l *list.List } // Tasker 任务接口 type Tasker interface { // 任务名称 Name() string // 执行任务时间间隔(秒) // 返回值 // = 0 时为指定时间执行的任务 Interval() uint64 // 每天指定时间执行的任务(hour:minute:second 时刻执行) // 返回值 // hour 小时( -1 时, 每小时定时执行) // minute 分钟 // second 秒 Timing() (hour, minute, second int) // 新增任务回调 //AddTask(handle TaskHandle) // 任务回调 //Task() TaskHandle // 执行任务(go 执行) // 参数 // now 当前时间 // hour 当前时间小时 // minute 当前时间分钟 // second 当前时间秒 Do(now time.Time, hour, minute, second int) } // NewTask 新任务 func NewTask() *Task { return &Task{l: list.New()} } // Add 加入新任务 func (t *Task) Add(tx Tasker) { t.l.PushBack(tx) } func (t *Task) do(nsec int64) { var ( interval uint64 hour, minute, second int ) now := time.Now() h := now.Hour() m := now.Minute() s := now.Second() t.Seconds++ for e := t.l.Front(); e != nil; e = e.Next() { v, _ := e.Value.(Tasker) interval = v.Interval() if interval > 1 { if nsec%int64(interval) == 0 { go v.Do(now, h, m, s) } continue } else if interval == 1 { // 每秒任务 go v.Do(now, h, m, s) continue } hour, minute, second = v.Timing() if second == s { if minute == m { switch hour { case h: go v.Do(now, h, m, s) case -1: // // 整点任务 go v.Do(now, h, m, s) } } } } } func (t *Task) Start(ctx context.Context) { defer func() { if rcv := recover(); rcv != nil { log.Println("Task recover()", rcv) } }() ts := time.NewTicker(1 * time.Second) nsecs := int64(0) for { select { case <-ctx.Done(): log.Println("Exit") return case <-ts.C: t.do(nsecs) nsecs++ } } } // ***************** TaskElement begin ***************** // TaskElement 任务 type TaskElement struct { TaskName string TimeInterval uint64 Hour int Minute int Second int // N int64 Handle TaskFunc } func (t TaskElement) Name() string { return t.TaskName } func (t TaskElement) Interval() uint64 { return t.TimeInterval } func (t TaskElement) Timing() (hour, minute, second int) { return t.Hour, t.Minute, t.Second } func (t *TaskElement) AddTask(handle TaskFunc) { t.Handle = handle } func (t *TaskElement) TaskHandle() TaskFunc { return t.Handle } func (t *TaskElement) Do(now time.Time, hour, minute, second int) { t.Handle(t.TaskName, now) } // ***************** TaskElement end ***************** // NewSecondTasker new func NewSecondTask(name string, secs uint64, handle TaskFunc) *TaskElement { return &TaskElement{TaskName: name, Handle: handle, TimeInterval: secs} } // NewSecondTask new func NewMinuteTask(name string, mins uint64, handle TaskFunc) *TaskElement { return &TaskElement{TaskName: name, Handle: handle, TimeInterval: 60 * mins} } // NewHourTask new func NewHourTask(name string, handle TaskFunc) *TaskElement { return &TaskElement{TaskName: name, Handle: handle, Hour: -1, Minute: 0, Second: 0} } // NewSecondTasker new func NewDailyTask(name string, hour, minute, second int, handle TaskFunc) *TaskElement { return &TaskElement{TaskName: name, Handle: handle, Hour: hour, Minute: minute, Second: second, TimeInterval: 0} }