Skip to content

Commit

Permalink
cap counters at capacity
Browse files Browse the repository at this point in the history
  • Loading branch information
leeym committed Feb 8, 2025
1 parent 9ee5ca3 commit 657a927
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
4 changes: 4 additions & 0 deletions slidingwindow.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package limiters
import (
"context"
"fmt"
"math"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -57,6 +58,9 @@ func (s *SlidingWindow) Limit(ctx context.Context) (time.Duration, error) {
return 0, err
}

prev = int64(math.Min(float64(prev), float64(s.capacity+1)))
curr = int64(math.Min(float64(curr), float64(s.capacity+1)))

total := float64(prev*int64(ttl))/float64(s.rate) + float64(curr)
if total-float64(s.capacity) >= s.epsilon {
var wait time.Duration
Expand Down
24 changes: 24 additions & 0 deletions slidingwindow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,30 @@ func (s *LimitersTestSuite) TestSlidingWindowOverflowAndWait() {
}
}

func (s *LimitersTestSuite) TestSlidingWindowOverflowAndNoWait() {
capacity := int64(10)
clock := newFakeClock()
for name, bucket := range s.slidingWindows(capacity, time.Second, clock, 1e-9) {
s.Run(name, func() {
clock.reset()
for i := int64(0); i < capacity; i++ {
w, err := bucket.Limit(context.TODO())
s.Require().NoError(err)
s.Require().Equal(time.Duration(0), w)
}
w, err := bucket.Limit(context.TODO())
s.Require().Equal(l.ErrLimitExhausted, err)
expected := clock.Now().Add(w)
for i := int64(0); i < capacity; i++ {
w, err = bucket.Limit(context.TODO())
s.Require().Equal(l.ErrLimitExhausted, err)
actual := clock.Now().Add(w)
s.Require().Equal(expected, actual, i)
}
})
}
}

func BenchmarkSlidingWindows(b *testing.B) {
s := new(LimitersTestSuite)
s.SetT(&testing.T{})
Expand Down

0 comments on commit 657a927

Please sign in to comment.