backoff.go 1006 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. package util
  2. import "time"
  3. type Backoff struct {
  4. StartMillis, MaxIntervalMillis, MaxMillis int
  5. c chan bool
  6. done chan bool
  7. }
  8. func (b *Backoff) Start() <-chan bool {
  9. b.c = make(chan bool)
  10. b.done = make(chan bool)
  11. go b.backoff()
  12. return b.c
  13. }
  14. func (b *Backoff) Close() error {
  15. b.done <- true
  16. return nil
  17. }
  18. func (b *Backoff) backoff() {
  19. if b.StartMillis == 0 && b.MaxIntervalMillis == 0 {
  20. b.StartMillis = 100
  21. b.MaxIntervalMillis = 2000
  22. b.MaxMillis = 300000
  23. }
  24. start := time.Now()
  25. currentMillis := b.StartMillis
  26. for {
  27. writeVal := true
  28. if time.Now().Sub(start) > (time.Duration(b.MaxMillis) * time.Millisecond) {
  29. b.c <- false
  30. }
  31. select {
  32. case <-b.done:
  33. close(b.done)
  34. close(b.c)
  35. return
  36. case b.c <- writeVal:
  37. }
  38. time.Sleep(time.Duration(currentMillis) * time.Millisecond)
  39. currentMillis *= 2
  40. if currentMillis > b.MaxIntervalMillis {
  41. currentMillis = b.MaxIntervalMillis
  42. }
  43. }
  44. }