package setup import ( "context" "strings" "sync" "time" "forge.cadoles.com/cadoles/bouncer/internal/config" "github.com/pkg/errors" "github.com/redis/go-redis/v9" "gitlab.com/wpetit/goweb/logger" ) var clients sync.Map func NewSharedClient(conf config.RedisConfig) redis.UniversalClient { key := strings.Join(conf.Adresses, "|") + "|" + string(conf.Master) value, exists := clients.Load(key) if exists { if client, ok := (value).(redis.UniversalClient); ok { return client } } client := newRedisClient(conf) clients.Store(key, client) return client } func newRedisClient(conf config.RedisConfig) redis.UniversalClient { client := redis.NewUniversalClient(&redis.UniversalOptions{ Addrs: conf.Adresses, MasterName: string(conf.Master), ReadTimeout: time.Duration(conf.ReadTimeout), WriteTimeout: time.Duration(conf.WriteTimeout), DialTimeout: time.Duration(conf.DialTimeout), RouteByLatency: bool(conf.RouteByLatency), ContextTimeoutEnabled: bool(conf.ContextTimeoutEnabled), MaxRetries: int(conf.MaxRetries), PoolSize: int(conf.PoolSize), PoolTimeout: time.Duration(conf.PoolTimeout), MinIdleConns: int(conf.MinIdleConns), MaxIdleConns: int(conf.MaxIdleConns), ConnMaxIdleTime: time.Duration(conf.ConnMaxIdleTime), ConnMaxLifetime: time.Duration(conf.ConnMaxLifetime), }) go func() { ctx := logger.With(context.Background(), logger.F("adresses", conf.Adresses), logger.F("master", conf.Master), ) timer := time.NewTicker(time.Duration(conf.PingInterval)) defer timer.Stop() connected := true for range timer.C { if _, err := client.Ping(ctx).Result(); err != nil { logger.Error(ctx, "redis disconnected", logger.CapturedE(errors.WithStack(err))) connected = false continue } if !connected { logger.Info(ctx, "redis reconnected") connected = true } } }() return client }