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