27
28
// NewLocalGate create a new timer gate instance
30
>
lg := &LocalGateImpl{
31
>
timer: time.NewTimer(0),
32
>
nextWakeupTime: time.Time{},
33
>
fireCh: make(chan struct{}, 1),
34
>
closeCh: make(chan struct{}),
35
>
timeSource: timeSource,
36
>
}
37
>
// the timer should be stopped when initialized
38
>
if !lg.timer.Stop() {
39
// drain the existing signal if exist
40
<-lg.timer.C
41
}
42
44
>
defer close(lg.fireCh)
45
>
defer lg.timer.Stop()
46
>
loop:
47
>
for {
48
>
select {
50
>
select {
51
// re-transmit on gateC
53
default:
54
}
55
57
>
// closed; cleanup and quit
58
>
break loop
59
}
60
}
61
}()
62
64
}
65
66
// FireCh return the channel which will be fired when time is up
68
>
return lg.fireCh
69
>
}
70
71
// FireAfter check will the timer get fired after a certain time
73
>
return lg.nextWakeupTime.After(now)
74
>
}
75
76
// Update the timer gate, return true if update is a success.
77
// Success means timer is idle or timer is set with a sooner time to fire
79
>
// NOTE: negative duration will make the timer fire immediately
80
>
now := lg.timeSource.Now()
81
>
82
>
if lg.timer.Stop() && lg.nextWakeupTime.Before(nextTime) {
83
// this means the timer, before stopped, is active && next wake-up time do not have to be updated
84
lg.timer.Reset(lg.nextWakeupTime.Sub(now))