mirror of
https://github.com/soypat/lneto.git
synced 2026-08-18 13:44:02 +00:00
implement a new backoff abstraction (#75)
This commit is contained in:
+11
-56
@@ -2,61 +2,16 @@ package internal
|
||||
|
||||
import "time"
|
||||
|
||||
type BackoffFlags uint8
|
||||
|
||||
const (
|
||||
BackoffHasPriority BackoffFlags = 1 << iota
|
||||
BackoffCriticalPath
|
||||
BackoffTCPConn
|
||||
)
|
||||
|
||||
const backoffMinWait = time.Microsecond
|
||||
|
||||
func backoffMaxWait(priority BackoffFlags) time.Duration {
|
||||
switch {
|
||||
case priority&BackoffCriticalPath != 0:
|
||||
return 1 * time.Millisecond
|
||||
case priority&BackoffTCPConn != 0:
|
||||
return 5 * time.Millisecond
|
||||
default:
|
||||
return time.Second >> (priority & BackoffHasPriority)
|
||||
}
|
||||
}
|
||||
|
||||
func NewBackoff(priority BackoffFlags) Backoff {
|
||||
return Backoff{
|
||||
wait: uint32(backoffMinWait),
|
||||
maxWait: uint32(backoffMaxWait(priority)),
|
||||
startWait: uint32(backoffMinWait),
|
||||
}
|
||||
}
|
||||
|
||||
// A Backoff with a non-zero MaxWait is ready for use.
|
||||
type Backoff struct {
|
||||
// wait defines the amount of time that Miss will wait on next call.
|
||||
wait uint32
|
||||
// Maximum allowable value for Wait.
|
||||
maxWait uint32
|
||||
// startWait is the intial Wait value, as well as the value that Wait takes after a call to Hit.
|
||||
startWait uint32
|
||||
}
|
||||
|
||||
// Hit sets eb.Wait to the StartWait value.
|
||||
func (eb *Backoff) Hit() {
|
||||
if eb.maxWait == 0 {
|
||||
panic("MaxWait cannot be zero")
|
||||
}
|
||||
eb.wait = eb.startWait
|
||||
}
|
||||
|
||||
// Miss sleeps for eb.Wait and increases eb.Wait exponentially.
|
||||
func (eb *Backoff) Miss() {
|
||||
if eb.maxWait == 0 {
|
||||
panic("MaxWait cannot be zero")
|
||||
}
|
||||
time.Sleep(time.Duration(eb.wait))
|
||||
eb.wait *= 2
|
||||
if eb.wait > eb.maxWait {
|
||||
eb.wait = eb.maxWait
|
||||
// ConnRWBackoff implements exponential backoff suitable for TCP connection
|
||||
// read/write polling. It starts at 1us and caps at 5ms, doubling on each consecutive backoff.
|
||||
func ConnRWBackoff(consecutiveBackoffs int) {
|
||||
const (
|
||||
minWait = time.Microsecond >> 1
|
||||
maxWait = 5 * time.Millisecond
|
||||
)
|
||||
wait := minWait << consecutiveBackoffs
|
||||
if wait > maxWait {
|
||||
wait = maxWait
|
||||
}
|
||||
time.Sleep(wait)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user