diff --git a/Makefile b/Makefile index b1a4354..ddfba04 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ bench: - go test -benchmem -run=NONE -bench . + go test -count 5 -benchmem -run=NONE -bench . test: lint tools @echo "==> Running tests..." @@ -11,4 +11,4 @@ lint: tools .PHONY: tools tools: @echo "==> Installing tools from tools.go..." - @awk -F'"' '/_/ {print $$2}' tools.go | xargs -I % go install % \ No newline at end of file + @awk -F'"' '/_/ {print $$2}' tools.go | xargs -I % go install % diff --git a/algorithm/cloudflare/redis_store.go b/algorithm/cloudflare/redis_store.go index 01a18c4..e11635c 100644 --- a/algorithm/cloudflare/redis_store.go +++ b/algorithm/cloudflare/redis_store.go @@ -2,7 +2,6 @@ package cloudflare import ( "context" - "fmt" "time" "github.com/go-redis/redis/v8" @@ -19,12 +18,11 @@ func (s *RedisDataStore) Inc(key string, window time.Time) error { ctx := context.Background() key = mapKey(key, window) - if _, err := s.RDB.TxPipelined(ctx, func(pipe redis.Pipeliner) error { - pipe.Incr(ctx, key) - pipe.Expire(ctx, key, s.ExpirationTime) + pipe := s.RDB.TxPipeline() + pipe.Incr(ctx, key) + pipe.Expire(ctx, key, s.ExpirationTime) - return nil - }); err != nil { + if _, err := pipe.Exec(ctx); err != nil { return err } @@ -49,5 +47,5 @@ func (s *RedisDataStore) Get(key string, previousWindow, currentWindow time.Time } func mapKey(key string, window time.Time) string { - return fmt.Sprintf("%s_%s", key, window.Format(time.RFC3339)) + return key + "_" + window.Format(time.RFC3339) } diff --git a/limiter_test.go b/limiter_test.go index 171b344..ca859c3 100644 --- a/limiter_test.go +++ b/limiter_test.go @@ -15,16 +15,9 @@ import ( "github.com/bringg/go_redis_ratelimit/algorithm/sliding_window" ) -var limiter = rateLimiter() - -func rateLimiter() *Limiter { - mr, err := miniredis.Run() - if err != nil { - panic(err) - } - +func rateLimiter(addr string) *Limiter { client := redis.NewClient(&redis.Options{ - Addr: mr.Addr(), + Addr: addr, }) if err := client.FlushDB(context.Background()).Err(); err != nil { @@ -40,7 +33,12 @@ func rateLimiter() *Limiter { } func TestLimiter_Allow(t *testing.T) { - l := rateLimiter() + mr, err := miniredis.Run() + require.NoError(t, err) + + defer mr.Close() + + l := rateLimiter(mr.Addr()) limit := &Limit{ Algorithm: sliding_window.AlgorithmName, @@ -84,7 +82,12 @@ func TestLimiter_Allow(t *testing.T) { }) } +// In benchmarks we will use real redis-server, since mini-redis impacts the benchmarks. +const redisAddress = "localhost:6379" + func Benchmark_CloudflareAlgorithm(b *testing.B) { + limiter := rateLimiter(redisAddress) + for i := 0; i < b.N; i++ { if _, err := limiter.Allow("cloudflare", &Limit{ Algorithm: cloudflare.AlgorithmName, @@ -97,6 +100,8 @@ func Benchmark_CloudflareAlgorithm(b *testing.B) { } func Benchmark_GcraAlgorithm(b *testing.B) { + limiter := rateLimiter(redisAddress) + for i := 0; i < b.N; i++ { if _, err := limiter.Allow("gcra", &Limit{ Algorithm: gcra.AlgorithmName, @@ -110,6 +115,8 @@ func Benchmark_GcraAlgorithm(b *testing.B) { } func Benchmark_SlidingWindowAlgorithm(b *testing.B) { + limiter := rateLimiter(redisAddress) + for i := 0; i < b.N; i++ { if _, err := limiter.Allow("sliding_window", &Limit{ Algorithm: sliding_window.AlgorithmName,