After the fix from #22 I found a bug:
With a small amount of Takes from the bucket, where Backend is a Redis with raceCheck=true then sometimes the expected version is higher than the actual one.
To replicate the issue I created a simple test:
func (s *LimitersTestSuite) TestTokenBucketRealClockRaceCheckRedisProblem() {
ttl := time.Second
limit := int64(2)
refillEvery := time.Duration(int64(ttl) / limit)
locker := l.NewLockNoop()
backend := l.NewTokenBucketRedis(s.redisClient, uuid.New().String(), ttl, true)
clk := l.NewSystemClock()
ctx := context.Background()
bucket := l.NewTokenBucket(
limit,
refillEvery,
locker,
backend,
clk,
nil,
)
for i := 0; i < 4; i++ {
wait, err := bucket.Limit(ctx)
if err != nil {
assert.ErrorIs(s.T(), err, l.ErrLimitExhausted)
}
if wait.Seconds() > 0 {
clk.Sleep(time.Second) // after a second all keys expired and the initial state was returned, but lastVersion is not cleared
}
}
}
After the fix from #22 I found a bug: With a small amount of Takes from the bucket, where Backend is a Redis with
raceCheck=true
then sometimes the expected version is higher than the actual one.To replicate the issue I created a simple test:
checkResponseFromRedis
returns error: