mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
AWS: Pass globals into Backoff struct
Thanks for the suggestion bprashanth!
This commit is contained in:
parent
b269e8f43c
commit
f8af47b645
@ -42,7 +42,7 @@ type CrossRequestRetryDelay struct {
|
|||||||
// Create a new CrossRequestRetryDelay
|
// Create a new CrossRequestRetryDelay
|
||||||
func NewCrossRequestRetryDelay() *CrossRequestRetryDelay {
|
func NewCrossRequestRetryDelay() *CrossRequestRetryDelay {
|
||||||
c := &CrossRequestRetryDelay{}
|
c := &CrossRequestRetryDelay{}
|
||||||
c.backoff.init()
|
c.backoff.init(decayIntervalSeconds, decayFraction, maxDelay)
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +90,10 @@ func (c *CrossRequestRetryDelay) AfterRetry(r *request.Request) {
|
|||||||
|
|
||||||
// Backoff manages a backoff that varies based on the recently observed failures
|
// Backoff manages a backoff that varies based on the recently observed failures
|
||||||
type Backoff struct {
|
type Backoff struct {
|
||||||
|
decayIntervalSeconds int64
|
||||||
|
decayFraction float64
|
||||||
|
maxDelay time.Duration
|
||||||
|
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
|
|
||||||
// We count all requests & the number of requests which hit a
|
// We count all requests & the number of requests which hit a
|
||||||
@ -100,10 +104,13 @@ type Backoff struct {
|
|||||||
lastDecay int64
|
lastDecay int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backoff) init() {
|
func (b *Backoff) init(decayIntervalSeconds int, decayFraction float64, maxDelay time.Duration) {
|
||||||
b.lastDecay = time.Now().Unix()
|
b.lastDecay = time.Now().Unix()
|
||||||
// Bias so that if the first request hits the limit we don't immediately apply the full delay
|
// Bias so that if the first request hits the limit we don't immediately apply the full delay
|
||||||
b.countRequests = 4
|
b.countRequests = 4
|
||||||
|
b.decayIntervalSeconds = int64(decayIntervalSeconds)
|
||||||
|
b.decayFraction = decayFraction
|
||||||
|
b.maxDelay = maxDelay
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the delay required for a request, also updating internal state to count this request
|
// Computes the delay required for a request, also updating internal state to count this request
|
||||||
@ -113,9 +120,9 @@ func (b *Backoff) ComputeDelayForRequest(now time.Time) time.Duration {
|
|||||||
|
|
||||||
// Apply exponential decay to the counters
|
// Apply exponential decay to the counters
|
||||||
timeDeltaSeconds := now.Unix() - b.lastDecay
|
timeDeltaSeconds := now.Unix() - b.lastDecay
|
||||||
if timeDeltaSeconds > decayIntervalSeconds {
|
if timeDeltaSeconds > b.decayIntervalSeconds {
|
||||||
intervals := float64(timeDeltaSeconds) / float64(decayIntervalSeconds)
|
intervals := float64(timeDeltaSeconds) / float64(b.decayIntervalSeconds)
|
||||||
decay := float32(math.Pow(decayFraction, intervals))
|
decay := float32(math.Pow(b.decayFraction, intervals))
|
||||||
b.countErrorsRequestLimit *= decay
|
b.countErrorsRequestLimit *= decay
|
||||||
b.countRequests *= decay
|
b.countRequests *= decay
|
||||||
b.lastDecay = now.Unix()
|
b.lastDecay = now.Unix()
|
||||||
@ -140,7 +147,7 @@ func (b *Backoff) ComputeDelayForRequest(now time.Time) time.Duration {
|
|||||||
// Delay by the max delay multiplied by the recent error rate
|
// Delay by the max delay multiplied by the recent error rate
|
||||||
// (i.e. we apply a linear delay function)
|
// (i.e. we apply a linear delay function)
|
||||||
// TODO: This is pretty arbitrary
|
// TODO: This is pretty arbitrary
|
||||||
delay := time.Nanosecond * time.Duration(float32(maxDelay.Nanoseconds())*errorFraction)
|
delay := time.Nanosecond * time.Duration(float32(b.maxDelay.Nanoseconds())*errorFraction)
|
||||||
// Round down to the nearest second for sanity
|
// Round down to the nearest second for sanity
|
||||||
return time.Second * time.Duration(int(delay.Seconds()))
|
return time.Second * time.Duration(int(delay.Seconds()))
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
// Test that we don't apply any delays when there are no errors
|
// Test that we don't apply any delays when there are no errors
|
||||||
func TestBackoffNoErrors(t *testing.T) {
|
func TestBackoffNoErrors(t *testing.T) {
|
||||||
b := &Backoff{}
|
b := &Backoff{}
|
||||||
b.init()
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
@ -47,7 +47,7 @@ func TestBackoffNoErrors(t *testing.T) {
|
|||||||
// delay and no-delay.
|
// delay and no-delay.
|
||||||
func TestBackoffAllErrors(t *testing.T) {
|
func TestBackoffAllErrors(t *testing.T) {
|
||||||
b := &Backoff{}
|
b := &Backoff{}
|
||||||
b.init()
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
// Warm up
|
// Warm up
|
||||||
@ -73,7 +73,7 @@ func TestBackoffAllErrors(t *testing.T) {
|
|||||||
// don't wait for delay in between requests)
|
// don't wait for delay in between requests)
|
||||||
func TestBackoffHitsMax(t *testing.T) {
|
func TestBackoffHitsMax(t *testing.T) {
|
||||||
b := &Backoff{}
|
b := &Backoff{}
|
||||||
b.init()
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
@ -97,7 +97,7 @@ func TestBackoffHitsMax(t *testing.T) {
|
|||||||
// no more errors.
|
// no more errors.
|
||||||
func TestBackoffRecovers(t *testing.T) {
|
func TestBackoffRecovers(t *testing.T) {
|
||||||
b := &Backoff{}
|
b := &Backoff{}
|
||||||
b.init()
|
b.init(decayIntervalSeconds, decayFraction, maxDelay)
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user