Skip to content

Instantly share code, notes, and snippets.

@arriqaaq
Created May 29, 2019 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arriqaaq/f3cdfdd9aa742a9179dd01dec9f3d981 to your computer and use it in GitHub Desktop.
Save arriqaaq/f3cdfdd9aa742a9179dd01dec9f3d981 to your computer and use it in GitHub Desktop.
// Closer holds the two things we need to close a goroutine and wait for it to finish: a chan
// to tell the goroutine to shut down, and a WaitGroup with which to wait for it to finish shutting
// down.
type Closer struct {
closed chan struct{}
waiting sync.WaitGroup
}
// NewCloser constructs a new Closer, with an initial count on the WaitGroup.
func NewCloser(initial int) *Closer {
ret := &Closer{closed: make(chan struct{})}
ret.waiting.Add(initial)
return ret
}
// AddRunning Add()'s delta to the WaitGroup.
func (lc *Closer) AddRunning(delta int) {
lc.waiting.Add(delta)
}
// Signal signals the HasBeenClosed signal.
func (lc *Closer) Signal() {
close(lc.closed)
}
// HasBeenClosed gets signaled when Signal() is called.
func (lc *Closer) HasBeenClosed() <-chan struct{} {
return lc.closed
}
// Done calls Done() on the WaitGroup.
func (lc *Closer) Done() {
lc.waiting.Done()
}
// Wait waits on the WaitGroup. (It waits for NewCloser's initial value, AddRunning, and Done
// calls to balance out.)
func (lc *Closer) Wait() {
lc.waiting.Wait()
}
// SignalAndWait calls Signal(), then Wait().
func (lc *Closer) SignalAndWait() {
lc.Signal()
lc.Wait()
}
----------Examle Usage---------------------
type Op struct {
closer *Closer
}
func NewOp(dur time.Duration) *Op {
op := &MergeOperator{
closer: NewCloser(1),
}
go op.Do(dur)
return op
}
func (op *Op) Do(dur time.Duration) {
ticker := time.NewTicker(dur)
defer op.closer.Done()
var stop bool
for {
select {
case <-op.closer.HasBeenClosed():
stop = true
case <-ticker.C: // wait for tick
}
if stop {
ticker.Stop()
break
}
}
}
func (op *Op) Stop() {
op.closer.SignalAndWait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment