prysm-pulse/shared/asyncutil/debounce.go
Victor Farazdagi 51f2cc18e5
Improves asyncutils/Debounce (#7189)
* improves asyncutils/debounce
* better handling of timeout test
* more tests
2020-09-08 14:49:28 +00:00

46 lines
1.1 KiB
Go

package asyncutil
import (
"context"
"time"
)
// Debounce events fired over a channel by a specified duration, ensuring no events
// are handled until a certain interval of time has passed.
func Debounce(ctx context.Context, interval time.Duration, eventsChan <-chan interface{}, handler func(interface{})) {
var timer *time.Timer
defer func() {
if timer != nil {
timer.Stop()
}
}()
for {
select {
// Wait until an event is triggered.
case event := <-eventsChan:
timer = time.NewTimer(interval)
loop:
for {
// If an event is received, wait the specified interval before calling the handler.
// If another event is received before the interval has passed, store
// it and reset the timer.
select {
case event = <-eventsChan:
// Reset timer.
timer.Stop()
timer = time.NewTimer(interval)
case <-timer.C:
// Stop the current timer, handle the request, and wait for more events.
timer.Stop()
handler(event)
break loop
case <-ctx.Done():
return
}
}
case <-ctx.Done():
return
}
}
}