tendermint/common/throttler.go

47 lines
867 B
Go

package common
import (
"sync/atomic"
"time"
)
/*
Throttler sends a struct{}{} to .Ch "dur" after the last .Set().
It's good for ensuring that something happens last after a burst of events.
*/
type Throttler struct {
Ch chan struct{}
quit chan struct{}
dur time.Duration
timer *time.Timer
isSet uint32
}
func NewThrottler(dur time.Duration) *Throttler {
var ch = make(chan struct{})
var quit = make(chan struct{})
var t = &Throttler{Ch: ch, dur: dur, quit: quit}
t.timer = time.AfterFunc(dur, t.fireHandler)
t.timer.Stop()
return t
}
func (t *Throttler) fireHandler() {
select {
case t.Ch <- struct{}{}:
atomic.StoreUint32(&t.isSet, 0)
case <-t.quit:
}
}
func (t *Throttler) Set() {
if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
t.timer.Reset(t.dur)
}
}
func (t *Throttler) Stop() bool {
close(t.quit)
return t.timer.Stop()
}