Created
May 29, 2019 17:31
-
-
Save arriqaaq/f3cdfdd9aa742a9179dd01dec9f3d981 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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