/
actor.go
61 lines (53 loc) · 1.03 KB
/
actor.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
package utils
type Actor struct {
in chan<- interface{}
out <-chan interface{}
done chan struct{}
}
func newActor() *Actor {
t := &Actor{done: make(chan struct{})}
t.in, t.out = InfiniteChannel()
go t.workRoutine()
return t
}
// Do runs the specified func in the using the actor routine
func (t *Actor) Do(f func()) {
select {
case t.in <- f:
case <-t.done:
}
}
// Do runs the specified func in the using the actor routine and returns the result
func (t *Actor) DoFunc(f func() interface{}) interface{} {
result := make(chan interface{})
select {
case t.in <- func() { result <- f() }:
case <-t.done:
return nil
}
return <-result
}
// WaitAllDone waits until all scheduled work has been done
func (t *Actor) WaitAllDone() {
done := make(chan struct{})
t.Do(func() { close(done) })
<-done
}
func (t *Actor) Close() {
close(t.done)
close(t.in)
}
func (t *Actor) workRoutine() {
for {
select {
case w, ok := <-t.out:
if !ok {
return
}
work := w.(func())
work()
case <-t.done:
return
}
}
}