package database import ( "context" "fmt" "sync" "time" "git.hujye.com/infrastructure/go-web-gin/config" "git.hujye.com/infrastructure/go-web-gin/logger" "github.com/redis/go-redis/v9" ) var ( rdb *redis.Client redisOnce sync.Once ) // GetRedis returns the redis.Client singleton instance. // It will initialize the connection on first call func GetRedis() *redis.Client { redisOnce.Do(func() { rdb = initRedis() }) return rdb } // initRedis initializes and returns a new redis.Client connection. // It will panic if connection fails func initRedis() *redis.Client { cfg := config.Get().Redis rdb := redis.NewClient(&redis.Options{ Addr: cfg.Addr, Password: cfg.Password, DB: cfg.DB, PoolSize: cfg.PoolSize, MinIdleConns: cfg.MinIdleConns, MaxRetries: cfg.MaxRetries, DialTimeout: time.Duration(cfg.DialTimeout) * time.Second, ReadTimeout: time.Duration(cfg.ReadTimeout) * time.Second, WriteTimeout: time.Duration(cfg.WriteTimeout) * time.Second, }) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := rdb.Ping(ctx).Err(); err != nil { logger.GetLogger().Error(nil, "redis connect failed", "addr", cfg.Addr, "error", err.Error()) panic(fmt.Sprintf("failed to connect to redis: %v", err)) } logger.GetLogger().Info(nil, "redis connected successfully", "addr", cfg.Addr, "db", cfg.DB) return rdb } // CloseRedis closes the redis connection. // Returns error if close fails, nil otherwise func CloseRedis() error { if rdb != nil { if err := rdb.Close(); err != nil { logger.GetLogger().Error(nil, "redis close failed", "error", err.Error()) return err } logger.GetLogger().Info(nil, "redis connection closed") } return nil }