Skip to content

Commit 3d3b5b3

Browse files
authored
chore(router): adaptive throttler decreasing throttling rate dynamically based on current throttled rate (#5931)
# Description Instead of decreasing throttling factor by `decreasePercentage` once `throttleTolerancePercentage` is surpassed, throttling factor is now being decreased `by throttledRate*decreasePercentage` ## Linear Ticket resolves PIPE-2095 ## Security - [x] The code changed/added as part of this pull request won't create any security issues with how the software is being used.
1 parent e5b0ab4 commit 3d3b5b3

File tree

2 files changed

+13
-8
lines changed

2 files changed

+13
-8
lines changed

router/throttler/adaptivethrottlercounter/algorithm_test.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func TestAdaptiveRateLimit(t *testing.T) {
1717
cfg := config.New()
1818
al := New("dest", cfg, config.SingleValueLoader(500*time.Millisecond))
1919
defer al.Shutdown()
20+
2021
t.Run("when there is a 429s in the last decrease limit counter window", func(t *testing.T) {
2122
al.ResponseCodeReceived(429)
2223
require.Eventually(t, func() bool {
@@ -30,21 +31,25 @@ func TestAdaptiveRateLimit(t *testing.T) {
3031
}, 2*time.Second, 100*time.Millisecond) // increases by 10% since there is no error in the last 2 seconds
3132
})
3233

33-
t.Run("429s less than resolution", func(t *testing.T) {
34-
for i := 0; i < 10; i++ {
34+
t.Run("429s less than threshold", func(t *testing.T) {
35+
for range 10 {
3536
al.ResponseCodeReceived(200)
3637
}
3738
al.ResponseCodeReceived(429)
38-
require.True(t, floatCheck(al.LimitFactor(), float64(0.8))) // does not change since 429s less than resolution
39+
40+
require.Eventually(t, func() bool {
41+
require.False(t, floatCheck(al.LimitFactor(), float64(0.7)), "limit factor should not decrease")
42+
return floatCheck(al.LimitFactor(), float64(0.9)) // eventually increases by 10% since there is no error in the last 2 seconds
43+
}, 3*time.Second, 100*time.Millisecond)
3944
})
4045

41-
t.Run("429s more than resolution", func(t *testing.T) {
42-
for i := 0; i < 5; i++ {
46+
t.Run("429s more than threshold", func(t *testing.T) {
47+
for range 4 {
4348
al.ResponseCodeReceived(200)
4449
}
45-
al.ResponseCodeReceived(429)
50+
al.ResponseCodeReceived(429) // throttledRate is 1/5 = 0.2 > 0.1 (throttleTolerancePercentage)
4651
require.Eventually(t, func() bool {
47-
return floatCheck(al.LimitFactor(), float64(0.5))
52+
return floatCheck(al.LimitFactor(), 0.84) // reduces by 6% (30%*0.2)
4853
}, time.Second, 100*time.Millisecond) // does not change since 429s less than resolution
4954
})
5055

router/throttler/adaptivethrottlercounter/decrease_limit_counter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func (c *decreaseLimitCounter) run(ctx context.Context, wg *sync.WaitGroup) {
4848
}
4949
c.counterMu.Unlock()
5050
if throttledRate > float64(c.throttleTolerancePercentage())/100 {
51-
c.limitFactor.Add(-float64(c.decreasePercentage.Load()) / 100)
51+
c.limitFactor.Add(-throttledRate * float64(c.decreasePercentage.Load()) / 100)
5252
if err := c.wait(ctx); err != nil {
5353
return
5454
}

0 commit comments

Comments
 (0)