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.

73 lines
1.4 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package common
  2. import (
  3. "sync"
  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. Name string
  14. Ch chan struct{}
  15. quit chan struct{}
  16. dur time.Duration
  17. mtx sync.Mutex
  18. timer *time.Timer
  19. isSet bool
  20. }
  21. func NewThrottleTimer(name string, dur time.Duration) *ThrottleTimer {
  22. var ch = make(chan struct{})
  23. var quit = make(chan struct{})
  24. var t = &ThrottleTimer{Name: name, Ch: ch, dur: dur, quit: quit}
  25. t.timer = time.AfterFunc(dur, t.fireRoutine)
  26. t.timer.Stop()
  27. return t
  28. }
  29. func (t *ThrottleTimer) fireRoutine() {
  30. t.mtx.Lock()
  31. defer t.mtx.Unlock()
  32. select {
  33. case t.Ch <- struct{}{}:
  34. t.isSet = false
  35. case <-t.quit:
  36. // do nothing
  37. default:
  38. t.timer.Reset(t.dur)
  39. }
  40. }
  41. func (t *ThrottleTimer) Set() {
  42. t.mtx.Lock()
  43. defer t.mtx.Unlock()
  44. if !t.isSet {
  45. t.isSet = true
  46. t.timer.Reset(t.dur)
  47. }
  48. }
  49. func (t *ThrottleTimer) Unset() {
  50. t.mtx.Lock()
  51. defer t.mtx.Unlock()
  52. t.isSet = false
  53. t.timer.Stop()
  54. }
  55. // For ease of .Stop()'ing services before .Start()'ing them,
  56. // we ignore .Stop()'s on nil ThrottleTimers
  57. func (t *ThrottleTimer) Stop() bool {
  58. if t == nil {
  59. return false
  60. }
  61. close(t.quit)
  62. t.mtx.Lock()
  63. defer t.mtx.Unlock()
  64. return t.timer.Stop()
  65. }