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.

48 lines
987 B

10 years ago
10 years ago
10 years ago
  1. package common
  2. import (
  3. "sync/atomic"
  4. "time"
  5. )
  6. /*
  7. ThrottleTimer fires an event at most "dur" after each .Set() call.
  8. If a short burst of .Set() calls happens, ThrottleTimer fires once.
  9. If a long continuous burst of .Set() calls happens, ThrottleTimer fires
  10. at most once every "dur".
  11. */
  12. type ThrottleTimer struct {
  13. Ch chan struct{}
  14. quit chan struct{}
  15. dur time.Duration
  16. timer *time.Timer
  17. isSet uint32
  18. }
  19. func NewThrottleTimer(dur time.Duration) *ThrottleTimer {
  20. var ch = make(chan struct{})
  21. var quit = make(chan struct{})
  22. var t = &ThrottleTimer{Ch: ch, dur: dur, quit: quit}
  23. t.timer = time.AfterFunc(dur, t.fireRoutine)
  24. t.timer.Stop()
  25. return t
  26. }
  27. func (t *ThrottleTimer) fireRoutine() {
  28. select {
  29. case t.Ch <- struct{}{}:
  30. atomic.StoreUint32(&t.isSet, 0)
  31. case <-t.quit:
  32. }
  33. }
  34. func (t *ThrottleTimer) Set() {
  35. if atomic.CompareAndSwapUint32(&t.isSet, 0, 1) {
  36. t.timer.Reset(t.dur)
  37. }
  38. }
  39. func (t *ThrottleTimer) Stop() bool {
  40. close(t.quit)
  41. return t.timer.Stop()
  42. }