mirror of
https://github.com/keven1024/015.git
synced 2026-06-06 12:29:34 +00:00
fix(redis): retry with exponential backoff on startup
rueidis.NewClient pings Redis immediately; if the container starts before Redis is ready the backend fatals. Retry up to 10 times with exponential backoff (300ms → 810ms → 2.2s → … capped at 15s).
This commit is contained in:
@@ -1,22 +1,52 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"time"
|
||||
"github.com/redis/rueidis"
|
||||
)
|
||||
|
||||
var rdb rueidis.Client
|
||||
|
||||
const (
|
||||
redisMaxRetries = 10
|
||||
redisBaseDelay = 300 * time.Millisecond
|
||||
redisBackoffFactor = 2.7
|
||||
redisMaxDelay = 15 * time.Second
|
||||
)
|
||||
|
||||
func InitRedis() error {
|
||||
opt, err := rueidis.ParseURL(GetEnv("redis.url"))
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("invalid redis url: %w", err)
|
||||
}
|
||||
client, err := rueidis.NewClient(opt)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
var lastErr error
|
||||
for attempt := range redisMaxRetries {
|
||||
var client rueidis.Client
|
||||
client, lastErr = rueidis.NewClient(opt)
|
||||
if lastErr == nil {
|
||||
rdb = client
|
||||
return nil
|
||||
}
|
||||
if attempt == redisMaxRetries-1 {
|
||||
break
|
||||
}
|
||||
delay := time.Duration(math.Min(
|
||||
float64(redisBaseDelay)*math.Pow(redisBackoffFactor, float64(attempt)),
|
||||
float64(redisMaxDelay),
|
||||
))
|
||||
slog.Warn("redis connection failed, retrying",
|
||||
"attempt", attempt+1,
|
||||
"maxRetries", redisMaxRetries,
|
||||
"retryIn", delay.String(),
|
||||
"error", lastErr,
|
||||
)
|
||||
time.Sleep(delay)
|
||||
}
|
||||
rdb = client
|
||||
return nil
|
||||
return fmt.Errorf("redis connection failed after %d attempts: %w", redisMaxRetries, lastErr)
|
||||
}
|
||||
|
||||
func GetRedisClient() rueidis.Client {
|
||||
|
||||
Reference in New Issue
Block a user