From 0b8aeaf50028504bbe830c047f01fd66c8e421ae Mon Sep 17 00:00:00 2001 From: gmarek Date: Mon, 5 Sep 2016 17:41:37 +0200 Subject: [PATCH] Make ExponentialFailureRateLimiter slightly slower and cap the backoff --- pkg/util/workqueue/default_rate_limiters.go | 6 +++--- .../workqueue/default_rate_limiters_test.go | 20 +++++++++---------- .../workqueue/rate_limitting_queue_test.go | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg/util/workqueue/default_rate_limiters.go b/pkg/util/workqueue/default_rate_limiters.go index 8b281158147..35caed4fa41 100644 --- a/pkg/util/workqueue/default_rate_limiters.go +++ b/pkg/util/workqueue/default_rate_limiters.go @@ -38,7 +38,7 @@ type RateLimiter interface { // both overall and per-item rate limitting. The overall is a token bucket and the per-item is exponential func DefaultControllerRateLimiter() RateLimiter { return NewMaxOfRateLimiter( - DefaultItemBasedRateLimiter(), + NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second), // 10 qps, 100 bucket size. This is only for retry speed and its only the overall factor (not per item) &BucketRateLimiter{Bucket: ratelimit.NewBucketWithRate(float64(10), int64(100))}, ) @@ -83,7 +83,7 @@ func NewItemExponentialFailureRateLimiter(baseDelay time.Duration, maxDelay time } func DefaultItemBasedRateLimiter() RateLimiter { - return NewItemExponentialFailureRateLimiter(1*time.Millisecond, 1000*time.Second) + return NewItemExponentialFailureRateLimiter(time.Millisecond, 1000*time.Second) } func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration { @@ -94,7 +94,7 @@ func (r *ItemExponentialFailureRateLimiter) When(item interface{}) time.Duration r.failures[item] = r.failures[item] + 1 // The backoff is capped such that 'calculated' value never overflows. - backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow10(exp) + backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow(2, float64(exp)) if backoff > math.MaxInt64 { return r.maxDelay } diff --git a/pkg/util/workqueue/default_rate_limiters_test.go b/pkg/util/workqueue/default_rate_limiters_test.go index e50cf453f03..91d34a31779 100644 --- a/pkg/util/workqueue/default_rate_limiters_test.go +++ b/pkg/util/workqueue/default_rate_limiters_test.go @@ -27,16 +27,16 @@ func TestItemExponentialFailureRateLimiter(t *testing.T) { if e, a := 1*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 10*time.Millisecond, limiter.When("one"); e != a { + if e, a := 2*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 100*time.Millisecond, limiter.When("one"); e != a { + if e, a := 4*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 1*time.Second, limiter.When("one"); e != a { + if e, a := 8*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 1*time.Second, limiter.When("one"); e != a { + if e, a := 16*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := 5, limiter.NumRequeues("one"); e != a { @@ -46,7 +46,7 @@ func TestItemExponentialFailureRateLimiter(t *testing.T) { if e, a := 1*time.Millisecond, limiter.When("two"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 10*time.Millisecond, limiter.When("two"); e != a { + if e, a := 2*time.Millisecond, limiter.When("two"); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := 2, limiter.NumRequeues("two"); e != a { @@ -68,7 +68,7 @@ func TestItemExponentialFailureRateLimiterOverFlow(t *testing.T) { for i := 0; i < 5; i++ { limiter.When("one") } - if e, a := 100000*time.Millisecond, limiter.When("one"); e != a { + if e, a := 32*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } @@ -83,7 +83,7 @@ func TestItemExponentialFailureRateLimiterOverFlow(t *testing.T) { for i := 0; i < 2; i++ { limiter.When("two") } - if e, a := 100*time.Minute, limiter.When("two"); e != a { + if e, a := 4*time.Minute, limiter.When("two"); e != a { t.Errorf("expected %v, got %v", e, a) } @@ -147,10 +147,10 @@ func TestMaxOfRateLimiter(t *testing.T) { if e, a := 5*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 10*time.Millisecond, limiter.When("one"); e != a { + if e, a := 5*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 100*time.Millisecond, limiter.When("one"); e != a { + if e, a := 5*time.Millisecond, limiter.When("one"); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := 3*time.Second, limiter.When("one"); e != a { @@ -166,7 +166,7 @@ func TestMaxOfRateLimiter(t *testing.T) { if e, a := 5*time.Millisecond, limiter.When("two"); e != a { t.Errorf("expected %v, got %v", e, a) } - if e, a := 10*time.Millisecond, limiter.When("two"); e != a { + if e, a := 5*time.Millisecond, limiter.When("two"); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := 2, limiter.NumRequeues("two"); e != a { diff --git a/pkg/util/workqueue/rate_limitting_queue_test.go b/pkg/util/workqueue/rate_limitting_queue_test.go index 5e3db0d162e..c02b3883f2c 100644 --- a/pkg/util/workqueue/rate_limitting_queue_test.go +++ b/pkg/util/workqueue/rate_limitting_queue_test.go @@ -44,7 +44,7 @@ func TestRateLimitingQueue(t *testing.T) { } queue.AddRateLimited("one") waitEntry = <-delayingQueue.waitingForAddCh - if e, a := 10*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { + if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { t.Errorf("expected %v, got %v", e, a) } if e, a := 2, queue.NumRequeues("one"); e != a { @@ -58,7 +58,7 @@ func TestRateLimitingQueue(t *testing.T) { } queue.AddRateLimited("two") waitEntry = <-delayingQueue.waitingForAddCh - if e, a := 10*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { + if e, a := 2*time.Millisecond, waitEntry.readyAt.Sub(fakeClock.Now()); e != a { t.Errorf("expected %v, got %v", e, a) }