12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- package util
- import "time"
- type Backoff struct {
- StartMillis, MaxIntervalMillis, MaxMillis int
- c chan bool
- done chan bool
- }
- func (b *Backoff) Start() <-chan bool {
- b.c = make(chan bool)
- b.done = make(chan bool)
- go b.backoff()
- return b.c
- }
- func (b *Backoff) Close() error {
- b.done <- true
- return nil
- }
- func (b *Backoff) backoff() {
- if b.StartMillis == 0 && b.MaxIntervalMillis == 0 {
- b.StartMillis = 100
- b.MaxIntervalMillis = 2000
- b.MaxMillis = 300000
- }
- start := time.Now()
- currentMillis := b.StartMillis
- for {
- writeVal := true
- if time.Now().Sub(start) > (time.Duration(b.MaxMillis) * time.Millisecond) {
- b.c <- false
- }
- select {
- case <-b.done:
- close(b.done)
- close(b.c)
- return
- case b.c <- writeVal:
- }
- time.Sleep(time.Duration(currentMillis) * time.Millisecond)
- currentMillis *= 2
- if currentMillis > b.MaxIntervalMillis {
- currentMillis = b.MaxIntervalMillis
- }
- }
- }
|