-
Notifications
You must be signed in to change notification settings - Fork 0
/
runqueue.go
70 lines (58 loc) · 966 Bytes
/
runqueue.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
package mx
import "fmt"
type (
step int
)
const (
_ step = iota
Init
Setup
)
type runqueue struct {
cur step
runs map[step][]func()
}
func (h *runqueue) call(s step, fn func()) error {
if h.runs == nil {
h.runs = make(map[step][]func())
}
h.runs[s] = append(h.runs[s], fn)
if h.cur >= s {
return h.do(s)
}
return nil
}
func (h *runqueue) recoved(fn func()) (err error) {
defer func() {
if _err := recover(); _err != nil {
switch x := _err.(type) {
case error:
err = x
case nil:
default:
err = fmt.Errorf("%v", x)
}
}
}()
fn()
return nil
}
func (h *runqueue) do(step step) error {
h.cur = step
var pops []int
defer func() {
// remove multi call
c := 0
for _, i := range pops {
h.runs[step] = append(h.runs[step][:i-c], h.runs[step][i-c+1:]...)
c++
}
}()
for i, fn := range h.runs[step] {
if err := h.recoved(fn); err != nil {
return err
}
pops = append(pops, i)
}
return nil
}