-
-
Notifications
You must be signed in to change notification settings - Fork 37
/
timerstack.go
77 lines (64 loc) · 1.68 KB
/
timerstack.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
// Package timerstack provides a timer which can
// execute multiple delayed functions one after one.
package timerstack
import (
"sync"
"time"
)
// Action is the function being executed.
// If the function returns false, the timer
// stack stops executing after this function.
type Action func() bool
type timer struct {
delay time.Duration
action Action
}
// TimerStack allows to stack multiple timers on
// top to be executed one after one.
type TimerStack struct {
stack []*timer
mtx sync.Mutex
currTimer *time.Timer
stopNext bool
}
// New returns a new empty TimerStack.
func New() *TimerStack {
return &TimerStack{
stack: make([]*timer, 0),
}
}
// After adds a new timer to the stack which is executed
// after the given time delay after the last executed
// timer. On execution, a is executed. If this function
// returns false, the execution stops after this function.
func (ts *TimerStack) After(d time.Duration, a Action) *TimerStack {
ts.stack = append(ts.stack, &timer{d, a})
return ts
}
// RunBlocking starts the timer queue blocking the
// current go-routine until all timers on the stack
// are executed or until the timer has been stoped.
func (ts *TimerStack) RunBlocking() {
for _, t := range ts.stack {
ts.mtx.Lock()
ts.currTimer = time.NewTimer(t.delay)
ts.mtx.Unlock()
<-ts.currTimer.C
ts.mtx.Lock()
exit := !t.action() || ts.stopNext
ts.mtx.Unlock()
if exit {
break
}
}
}
// Stop stops the timer stack execution.
func (ts *TimerStack) Stop() {
ts.mtx.Lock()
defer ts.mtx.Unlock()
if ts.currTimer == nil {
return
}
ts.stopNext = true
ts.currTimer.Stop()
}