-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathzcrontab.go
126 lines (113 loc) · 2.81 KB
/
zcrontab.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package zcrontab
import (
"errors"
"sync"
"time"
"github.com/gorhill/cronexpr"
"github.com/satori/go.uuid"
)
type ZCrontab struct {
zCrontabInfo map[string]interface{}
mut sync.RWMutex
}
type contrabInfo struct {
conStr string
args interface{}
f func(interface{})
}
type atInfo struct {
sec int
min int
hour int
day int
mon time.Month
year int
repeated bool
args interface{}
f func(interface{})
}
// NewZCrontab ...
func NewZCrontab() *ZCrontab {
zTimer := new(ZCrontab)
zTimer.zCrontabInfo = make(map[string]interface{})
go zTimer.startConsume()
return zTimer
}
// Crontab add a crontab task,cronStr is a crontab string,f and args is the callback and input
func (z *ZCrontab) Crontab(cronStr string, f func(interface{}), args interface{}) (string, error) {
_, erro := cronexpr.Parse(cronStr)
if erro != nil {
return "", errors.New("bad format string")
}
uuid := z.getUUID()
z.mut.Lock()
z.zCrontabInfo[uuid] = contrabInfo{
conStr: cronStr,
args: args,
f: f,
}
z.mut.Unlock()
return uuid, nil
}
// At add a at task, t is the task time, f and args is the callback and input, repeat indicate wheather
// the task will repeat every day(will ignore the date info)
func (z *ZCrontab) At(t time.Time, f func(interface{}), args interface{}, repeated bool) (string, error) {
uuid := z.getUUID()
z.mut.Lock()
z.zCrontabInfo[uuid] = atInfo{
sec: t.Second(),
min: t.Minute(),
hour: t.Hour(),
day: t.Day(),
mon: t.Month(),
year: t.Year(),
repeated: repeated,
args: args,
f: f,
}
z.mut.Unlock()
return uuid, nil
}
// RmAt remove the task
func (z *ZCrontab) RmAt(id string) {
z.mut.Lock()
delete(z.zCrontabInfo, id)
z.mut.Unlock()
}
func (z *ZCrontab) getUUID() string {
u1 := uuid.NewV4()
return u1.String()
}
func (z *ZCrontab) startConsume() {
ticker := time.NewTicker(time.Second)
for {
<-ticker.C
cur := time.Now()
z.mut.RLock()
for _, value := range z.zCrontabInfo {
atT, isAt := value.(atInfo)
if isAt {
if cur.Second() == atT.sec && cur.Minute() == atT.min && cur.Hour() == atT.hour {
if cur.Day() == atT.day && cur.Month() == atT.mon && cur.Year() == atT.year {
go atT.f(atT.args)
} else if atT.repeated == true {
go atT.f(atT.args)
}
}
} else {
if cur.Second() == 0 {
conInfo, isCon := value.(contrabInfo)
if isCon {
preMin := cur.Add(-1 * time.Minute)
nextTime := cronexpr.MustParse(conInfo.conStr).Next(preMin)
if nextTime.Weekday() == cur.Weekday() && nextTime.Month() == cur.Month() && nextTime.Day() == cur.Day() && nextTime.Hour() == cur.Hour() && nextTime.Minute() == cur.Minute() {
conT := value.(contrabInfo)
go conT.f(conT.args)
}
}
}
}
}
z.mut.RUnlock()
}
}