Files
top-wallpaper/redis/client.go
Ron Rise ff66877192
All checks were successful
🚨 Test Code Base / 🔍 🐹 Go Tests (push) Successful in 1m22s
🚨 Test Code Base / 🧹 Lint (push) Successful in 1m31s
🏗️✨ Build Workflow / 🖥️ 🔨 Build (push) Successful in 11m11s
update-deps (#1)
Reviewed-on: #1
Co-authored-by: Ron Rise <ron@siteworxpro.com>
Co-committed-by: Ron Rise <ron@siteworxpro.com>
2025-08-26 16:36:17 +00:00

120 lines
2.5 KiB
Go

package redis
import (
"context"
"errors"
"fmt"
"os"
"strconv"
"time"
"github.com/redis/go-redis/v9"
)
type contextKey string
const redisKey contextKey = "redisClient"
const CacheKey = "top-wallpaper:latestImage"
type Cache interface {
Get(key string) (string, error)
Set(key string, value string, expiration int64) error
Close() error
}
type Redis struct {
client *redis.Client
}
func NewRedis() (*Redis, error) {
redisUrl := os.Getenv("REDIS_URL")
if redisUrl == "" {
return nil, errors.New("REDIS_URL not set, cannot initialize Redis client")
}
redisPort := os.Getenv("REDIS_PORT")
if redisPort == "" {
redisPort = "6379"
}
redisDb := os.Getenv("REDIS_DB")
if redisDb == "" {
redisDb = "0"
}
redisDbInt, err := strconv.ParseInt(redisDb, 10, 64)
if err != nil {
return nil, errors.New("REDIS_DB is not a valid integer, cannot initialize Redis client")
}
rc := redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", redisUrl, redisPort),
Password: os.Getenv("REDIS_PASSWORD"),
DB: int(redisDbInt),
})
cmd := rc.Ping(context.Background())
if cmd.Err() != nil {
return nil, fmt.Errorf("could not connect to Redis: %v", cmd.Err())
}
if cmd.Val() != "PONG" {
return nil, fmt.Errorf("unexpected response from Redis: %s", cmd.Val())
}
return &Redis{
client: rc,
}, nil
}
func (r *Redis) Get(key string) (string, error) {
cmd := r.client.Get(context.Background(), key)
if cmd.Err() != nil {
if errors.Is(cmd.Err(), redis.Nil) {
return "", nil // Key does not exist
}
return "", fmt.Errorf("could not get value for key %s: %v", key, cmd.Err())
}
return cmd.Val(), nil
}
func (r *Redis) Set(key string, value string, expiration time.Duration) error {
cmd := r.client.Set(context.Background(), key, value, expiration)
if cmd.Err() != nil {
return fmt.Errorf("could not set value for key %s: %v", key, cmd.Err())
}
if cmd.Val() != "OK" {
return fmt.Errorf("unexpected response from Redis when setting key %s: %s", key, cmd.Val())
}
return nil
}
func (r *Redis) Close() error {
if r.client == nil {
return nil
}
err := r.client.Close()
if err != nil {
return fmt.Errorf("could not close Redis client: %v", err)
}
return nil
}
func WithContext(ctx context.Context, r *Redis) context.Context {
return context.WithValue(ctx, redisKey, r)
}
func FromContext(ctx context.Context) (*Redis, error) {
r, ok := ctx.Value(redisKey).(*Redis)
if !ok {
return nil, errors.New("no Redis client found in context")
}
if r == nil {
return nil, errors.New("redis client is nil")
}
return r, nil
}