-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsched.go
More file actions
61 lines (52 loc) · 1.3 KB
/
sched.go
File metadata and controls
61 lines (52 loc) · 1.3 KB
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
package chimer
import (
"time"
)
type Scheduler struct {
stop chan struct{}
frequency time.Duration
}
// NewScheduler creates a scheduler with the frequency of f duration. Value of f is restricted to 1s <= f <= 1m.
func NewScheduler(f time.Duration) *Scheduler {
if f < time.Second {
f = time.Second
} else if f > time.Minute {
f = time.Minute
}
return &Scheduler{
stop: make(chan struct{}),
frequency: f,
}
}
// Stop stops the scheduler.
func (s *Scheduler) Stop() {
close(s.stop)
}
// EveryQuarterHour calls f, with current time t and tolerance, every 0th, 15th, 30th and 45th minutes of the hour. The
// value for tolerance is based on specified frequency for Scheduler.
func (s *Scheduler) EveryQuarterHour(f func(t time.Time, tolerance time.Duration)) {
tolerance := s.frequency / 2
var last time.Time
for {
t := time.Now().Local()
nextMinuteWait := time.Minute - (time.Duration(t.Second())*time.Second + time.Duration(t.Nanosecond()))
wait := s.frequency
if nextMinuteWait < s.frequency {
wait = nextMinuteWait
}
timer := time.NewTimer(wait)
select {
case t = <-timer.C:
switch t.Minute() {
case 0, 15, 30, 45:
if last.IsZero() || t.Sub(last) > time.Minute {
last = t
go f(t, tolerance)
}
}
case <-s.stop:
timer.Stop()
return
}
}
}