tendermint/common/throttle_timer.go

49 lines
987 B
Go
Raw Normal View History

package common
import (
"sync/atomic"
"time"
)
2014-07-09 18:33:44 -07:00
/*
ThrottleTimer fires an event at most "dur" after each .Set() call.
If a short burst of .Set() calls happens, ThrottleTimer fires once.
If a long continuous burst of .Set() calls happens, ThrottleTimer fires
at most once every "dur".
2014-07-09 18:33:44 -07:00
*/
type ThrottleTimer struct {
Ch chan struct{}
quit chan struct{}
dur time.Duration
timer *time.Timer
isSet uint32
}
func NewThrottleTimer(dur time.Duration) *ThrottleTimer {
var ch = make(chan struct{})
var quit = make(chan struct{})
var t = &ThrottleTimer{Ch: ch, dur: dur, quit: quit}
2014-08-10 16:35:08 -07:00
t.timer = time.AfterFunc(dur, t.fireRoutine)
2014-07-09 18:33:44 -07:00
t.timer.Stop()
return t
}
2014-08-10 16:35:08 -07:00
func (t *ThrottleTimer) fireRoutine() {
select {
case t.Ch <- struct{}{}:
atomic.StoreUint32(&t.isSet, 0)
case <-t.quit:
}
}
func (t *ThrottleTimer) Set() {
if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
t.timer.Reset(t.dur)
}
}
func (t *ThrottleTimer) Stop() bool {
close(t.quit)
return t.timer.Stop()
}