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