-
Notifications
You must be signed in to change notification settings - Fork 0
/
cron.go
126 lines (98 loc) · 1.9 KB
/
cron.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 webext
import (
"io"
"sync"
"time"
"github.com/AspieSoft/goutil/crypt"
)
type cronJob struct {
interval int64
last *int64
cb func() bool
}
var cron map[string]cronJob = map[string]cronJob{}
var cronMU sync.Mutex
func init(){
go func() {
for {
time.Sleep(1 * time.Second)
now := time.Now().UnixMilli()
cronMU.Lock()
for key, c := range cron {
if now > *c.last + c.interval {
*cron[key].last = now
if !c.cb() {
delete(cron, key)
}
}
}
cronMU.Unlock()
}
}()
}
// NewCron adds a new, unnamed cron job to the queue
//
// minimum interval: 1 minute
//
// in the callback, return true to keep the job running,
// and return false to end the job
func NewCron(interval time.Duration, cb func() bool) error {
intrv := interval.Milliseconds()
if intrv < 60000 {
intrv = 60000
}
now := time.Now().UnixMilli()
cronMU.Lock()
defer cronMU.Unlock()
name := "+job:"+string(crypt.RandBytes(16))
loops := 1000
for loops > 0 {
if _, ok := cron[name]; !ok {
break
}
loops--
name += string(crypt.RandBytes(16))
}
if _, ok := cron[name]; ok {
return io.EOF
}
cron[name] = cronJob{
interval: intrv,
last: &now,
cb: cb,
}
return nil
}
// SetCron adds or overwrites a named cron job
func SetCron(name string, interval time.Duration, cb func() bool){
name = "#job:" + name
intrv := interval.Milliseconds()
if intrv < 60000 {
intrv = 60000
}
now := time.Now().UnixMilli()
cronMU.Lock()
defer cronMU.Unlock()
cron[name] = cronJob{
interval: intrv,
last: &now,
cb: cb,
}
}
// HasCron checks if a named cron job exists
func HasCron(name string) bool {
name = "#job:" + name
cronMU.Lock()
defer cronMU.Unlock()
if _, ok := cron[name]; ok {
return true
}
return false
}
// DelCron removes a named cron job
func DelCron(name string) {
name = "#job:" + name
cronMU.Lock()
defer cronMU.Unlock()
delete(cron, name)
}