package redis import ( "context" "fmt" "time" "tm/pkg/logger" "github.com/redis/go-redis/v9" ) // Config holds Redis configuration type Config struct { Host string `json:"host"` Port int `json:"port"` Password string `json:"password"` DB int `json:"db"` PoolSize int `json:"pool_size"` } // Client represents a Redis client interface type Client interface { Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error Get(ctx context.Context, key string) (string, error) Incr(ctx context.Context, key string) (int64, error) Expire(ctx context.Context, key string, expiration time.Duration) error Del(ctx context.Context, keys ...string) error Exists(ctx context.Context, keys ...string) (int64, error) Close() error } // client implements the Client interface type client struct { rdb *redis.Client } // NewClient creates a new Redis client func NewClient(config *Config, logger logger.Logger) (Client, error) { if config == nil { return nil, fmt.Errorf("redis config is required") } addr := fmt.Sprintf("%s:%d", config.Host, config.Port) rdb := redis.NewClient(&redis.Options{ Addr: addr, Password: config.Password, DB: config.DB, PoolSize: config.PoolSize, }) // Test the connection ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() if err := rdb.Ping(ctx).Err(); err != nil { logger.Error("Failed to connect to Redis", map[string]interface{}{ "host": config.Host, "port": config.Port, "error": err.Error(), }) return nil, fmt.Errorf("failed to connect to Redis: %w", err) } logger.Info("Successfully connected to Redis", map[string]interface{}{ "host": config.Host, "port": config.Port, "db": config.DB, }) return &client{rdb: rdb}, nil } // Set sets a key-value pair with expiration func (c *client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error { return c.rdb.Set(ctx, key, value, expiration).Err() } // Get retrieves a value by key func (c *client) Get(ctx context.Context, key string) (string, error) { return c.rdb.Get(ctx, key).Result() } // Incr increments a key's integer value. func (c *client) Incr(ctx context.Context, key string) (int64, error) { return c.rdb.Incr(ctx, key).Result() } // Expire sets a timeout on a key. func (c *client) Expire(ctx context.Context, key string, expiration time.Duration) error { return c.rdb.Expire(ctx, key, expiration).Err() } // Del deletes one or more keys func (c *client) Del(ctx context.Context, keys ...string) error { return c.rdb.Del(ctx, keys...).Err() } // Exists checks if one or more keys exist func (c *client) Exists(ctx context.Context, keys ...string) (int64, error) { return c.rdb.Exists(ctx, keys...).Result() } // Close closes the Redis connection func (c *client) Close() error { return c.rdb.Close() }