ソースを参照

feat add task fun

Ken 2 日 前
コミット
3440077d7f
1 ファイル変更182 行追加0 行削除
  1. 182 0
      task.go

+ 182 - 0
task.go

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