/
timer.go
102 lines (92 loc) · 2.05 KB
/
timer.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
package utils
import (
"errors"
"time"
"github.com/kevinyjn/gocom/logger"
)
// Timer for processs
type Timer struct {
timer *time.Ticker
delay *time.Timer
durationMillisec int64
cb TimerCallback
delegate interface{}
}
// TimerCallback callback
type TimerCallback func(*Timer, time.Time, interface{})
// NewTimer and run the timer
func NewTimer(delayMillisec int64, durationMillisec int64, cb TimerCallback, delegate interface{}) (*Timer, error) {
timer := &Timer{}
err := timer.Start(delayMillisec, durationMillisec, cb, delegate)
return timer, err
}
// Start the timer
func (p *Timer) Start(delayMillisec int64, durationMillisec int64, cb TimerCallback, delegate interface{}) error {
if nil == cb {
logger.Error.Printf("Starting timer while giving nil callback")
return errors.New("Timer callback should not be empty")
}
if 0 == durationMillisec {
logger.Error.Printf("Starting timer while giving zero duration")
return errors.New("Timer duration should not be zero")
}
if nil != p.timer {
p.timer.Stop()
}
if nil != p.delay {
p.delay.Stop()
}
if 0 >= delayMillisec {
delayMillisec = 1
}
p.cb = cb
p.delegate = delegate
p.durationMillisec = durationMillisec
p.timer = nil
p.delay = time.NewTimer(time.Millisecond * time.Duration(delayMillisec))
go p.runDelay()
return nil
}
// Stop the timer
func (p *Timer) Stop() {
if nil != p.timer {
p.timer.Stop()
p.timer = nil
}
if nil != p.delay {
p.delay.Stop()
p.delay = nil
}
}
func (p *Timer) runDelay() {
for nil != p.delay {
select {
case tim := <-p.delay.C:
p.delay.Stop()
p.delay = nil
p.onTrigger(tim)
if nil != p.timer {
p.timer.Stop()
}
if p.durationMillisec > 0 {
p.timer = time.NewTicker(time.Millisecond * time.Duration(p.durationMillisec))
go p.runTimer()
}
break
}
}
}
func (p *Timer) runTimer() {
for nil != p.timer {
select {
case tim := <-p.timer.C:
p.onTrigger(tim)
break
}
}
}
func (p *Timer) onTrigger(tim time.Time) {
if nil != p.cb {
go p.cb(p, tim, p.delegate)
}
}