// Package cache provides optional Redis cache support. package cache import ( "context" "encoding/json" "errors" "fmt" "time" "git.kirsle.net/apps/gophertype/pkg/settings" redis "github.com/go-redis/redis/v8" ) // Global Redis configuration. var ( RedisHost = "localhost" RedisPort = 6379 RedisDB = 0 RedisClient *redis.Client ready bool ) // Error codes var ( ErrNotReady = errors.New("RedisClient not ready") ) // Connect to Redis after loading the details from the site's settings.json. func Connect() error { set := settings.Current if set.RedisEnabled { RedisClient = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", set.RedisHost, set.RedisPort), DB: set.RedisDB, }) return nil } return errors.New("Redis not enabled in .settings.json") } // SetEx sets a cache key with expiration. func SetEx(key string, value string, exp int64) error { if RedisClient == nil { return ErrNotReady } err := RedisClient.Set(context.Background(), key, value, time.Duration(exp)*time.Second).Err() return err } // Get a cache key. func Get(key string) (string, error) { if RedisClient == nil { return "", ErrNotReady } val, err := RedisClient.Get(context.Background(), key).Result() return val, err } // GetJSON gets a JSON serialized value out of Redis. func GetJSON(key string, v any) error { if val, err := Get(key); err != nil { return err } else { return json.Unmarshal([]byte(val), v) } } // Set sets a JSON serializable object in Redis. func SetJSON(key string, v interface{}, expire time.Duration) error { bin, err := json.Marshal(v) if err != nil { return err } _, err = RedisClient.Set(context.Background(), key, bin, expire).Result() if err != nil { return err } return nil } // Delete a key from Redis. func Delete(key string) error { return RedisClient.Del(context.Background(), key).Err() }