You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

46 lines
867 B

10 years ago
10 years ago
  1. package common
  2. import (
  3. "sync/atomic"
  4. "time"
  5. )
  6. /*
  7. Throttler sends a struct{}{} to .Ch "dur" after the last .Set().
  8. It's good for ensuring that something happens last after a burst of events.
  9. */
  10. type Throttler struct {
  11. Ch chan struct{}
  12. quit chan struct{}
  13. dur time.Duration
  14. timer *time.Timer
  15. isSet uint32
  16. }
  17. func NewThrottler(dur time.Duration) *Throttler {
  18. var ch = make(chan struct{})
  19. var quit = make(chan struct{})
  20. var t = &Throttler{Ch: ch, dur: dur, quit: quit}
  21. t.timer = time.AfterFunc(dur, t.fireHandler)
  22. t.timer.Stop()
  23. return t
  24. }
  25. func (t *Throttler) fireHandler() {
  26. select {
  27. case t.Ch <- struct{}{}:
  28. atomic.StoreUint32(&t.isSet, 0)
  29. case <-t.quit:
  30. }
  31. }
  32. func (t *Throttler) Set() {
  33. if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
  34. t.timer.Reset(t.dur)
  35. }
  36. }
  37. func (t *Throttler) Stop() bool {
  38. close(t.quit)
  39. return t.timer.Stop()
  40. }