|
@@ -0,0 +1,182 @@
|
|
|
|
|
+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}
|
|
|
|
|
+}
|