breaker.mx raw
1 package breaker
2
3 import (
4 "git.smesh.lol/moxie/pkg/mxutil"
5 "time"
6 )
7
8 func Closed(done chan struct{}) (closed bool) {
9 if done == nil {
10 return false
11 }
12 select {
13 case <-done:
14 return true
15 default:
16 return false
17 }
18 }
19
20 type Deadline struct {
21 at time.Time
22 done chan struct{}
23 }
24
25 func After(d time.Duration) (done chan struct{}, dl *Deadline) {
26 done = chan struct{}{}
27 dl = &Deadline{time.Now().Add(d), done}
28 return done, dl
29 }
30
31 func (dl *Deadline) Fire(now time.Time) (fired bool) {
32 if dl == nil || dl.done == nil || Closed(dl.done) {
33 return false
34 }
35 if now.Before(dl.at) {
36 return false
37 }
38 close(dl.done)
39 return true
40 }
41
42 func (g *Group) Add(done chan struct{}) {
43 g.breakers = mxutil.Ensure(g.breakers, 1)
44 push(g.breakers, done)
45 }
46
47 func (g *Group) Close() {
48 for _, b := range g.breakers {
49 if b != nil && !Closed(b) {
50 close(b)
51 }
52 }
53 g.breakers = g.breakers[:0]
54 }
55
56 type Group struct {
57 breakers []chan struct{}
58 }
59