parent
71337de24d
commit
0d95101f50
@ -0,0 +1,60 @@ |
|||||||
|
package p2p |
||||||
|
|
||||||
|
import "time" |
||||||
|
|
||||||
|
// Backoff is a backoff sleeper.
|
||||||
|
type Backoff interface { |
||||||
|
Reset() |
||||||
|
Sleep() |
||||||
|
Backoff() |
||||||
|
} |
||||||
|
|
||||||
|
// BackoffBase is the base implementation of backoff sleeper. It handles the
|
||||||
|
// minimum/current/maximum backoff logic. If maximum backoff is 0, there is no
|
||||||
|
// maximum.
|
||||||
|
type BackoffBase struct { |
||||||
|
Min, Cur, Max time.Duration |
||||||
|
} |
||||||
|
|
||||||
|
func NewBackoffBase(min, max time.Duration) *BackoffBase{ |
||||||
|
return &BackoffBase{min, min, max} |
||||||
|
} |
||||||
|
|
||||||
|
// Reset the current sleep duration to its minimum value.
|
||||||
|
func (b *BackoffBase) Reset() { |
||||||
|
b.Cur = b.Min |
||||||
|
} |
||||||
|
|
||||||
|
// Sleep for the current duration, then adjust the duration.
|
||||||
|
func (b *BackoffBase) Sleep() { |
||||||
|
if b.Cur < b.Min { |
||||||
|
b.Cur = b.Min |
||||||
|
} |
||||||
|
time.Sleep(b.Cur) |
||||||
|
b.Backoff() |
||||||
|
if b.Max != 0 && b.Cur > b.Max { |
||||||
|
b.Cur = b.Max |
||||||
|
} |
||||||
|
if b.Cur < b.Min { |
||||||
|
b.Cur = b.Min |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Adjust the duration. Subtypes shall implement this.
|
||||||
|
func (b *BackoffBase) Backoff() { |
||||||
|
// default implementation does not backoff
|
||||||
|
} |
||||||
|
|
||||||
|
// Exponential backoff.
|
||||||
|
type ExpBackoff struct { |
||||||
|
BackoffBase |
||||||
|
Factor float64 |
||||||
|
} |
||||||
|
|
||||||
|
func NewExpBackoff(min, max time.Duration, factor float64) *ExpBackoff { |
||||||
|
return &ExpBackoff{*NewBackoffBase(min, max), factor} |
||||||
|
} |
||||||
|
|
||||||
|
func (b *ExpBackoff) Backoff() { |
||||||
|
b.Cur = time.Duration(float64(b.Cur) * b.Factor) |
||||||
|
} |
Loading…
Reference in new issue