mirror of
https://github.com/traefik/traefik.git
synced 2026-06-19 07:36:07 +00:00
Create the redis rate limiter script lazily
This commit is contained in:
@@ -2,6 +2,7 @@ package ratelimiter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
@@ -61,6 +62,10 @@ end
|
||||
redis.call('hset', key, 'last', t, 'tokens', tokens)
|
||||
redis.call('expire', key, ttl)
|
||||
|
||||
return {tostring(true), tostring(wait_duration),tostring(tokens)}`
|
||||
return {tostring(true), tostring(wait_duration), tostring(tokens)}`
|
||||
|
||||
var AllowTokenBucketScript = redis.NewScript(AllowTokenBucketRaw)
|
||||
// LoadTokenBucketScript loads a token bucket script.
|
||||
// Exposed so it can be overridden by Traefik Hub.
|
||||
var LoadTokenBucketScript = sync.OnceValues(func() (*redis.Script, error) {
|
||||
return redis.NewScript(AllowTokenBucketRaw), nil
|
||||
})
|
||||
|
||||
@@ -23,6 +23,7 @@ type redisLimiter struct {
|
||||
logger *zerolog.Logger
|
||||
ttl int
|
||||
client Rediser
|
||||
script *redis.Script
|
||||
}
|
||||
|
||||
func newRedisLimiter(ctx context.Context, rate rate.Limit, burst int64, maxDelay time.Duration, ttl int, config dynamic.RateLimit, logger *zerolog.Logger) (limiter, error) {
|
||||
@@ -64,6 +65,11 @@ func newRedisLimiter(ctx context.Context, rate rate.Limit, burst int64, maxDelay
|
||||
}
|
||||
}
|
||||
|
||||
script, err := LoadTokenBucketScript()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("loading bucket script: %w", err)
|
||||
}
|
||||
|
||||
return &redisLimiter{
|
||||
rate: rate,
|
||||
burst: burst,
|
||||
@@ -72,6 +78,7 @@ func newRedisLimiter(ctx context.Context, rate rate.Limit, burst int64, maxDelay
|
||||
logger: logger,
|
||||
ttl: ttl,
|
||||
client: redis.NewUniversalClient(options),
|
||||
script: script,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -98,7 +105,7 @@ func (r *redisLimiter) evaluateScript(ctx context.Context, key string) (bool, *t
|
||||
time.Now().UnixMicro(),
|
||||
r.maxDelay.Microseconds(),
|
||||
}
|
||||
v, err := AllowTokenBucketScript.Run(ctx, r.client, []string{redisPrefix + key}, params...).Result()
|
||||
v, err := r.script.Run(ctx, r.client, []string{redisPrefix + key}, params...).Result()
|
||||
if err != nil {
|
||||
return false, nil, fmt.Errorf("running script: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user