2021-05-31 23:11:01 +00:00
|
|
|
// Package cache provides optional Redis cache support.
|
|
|
|
package cache
|
|
|
|
|
|
|
|
import (
|
2022-12-06 05:07:52 +00:00
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"git.kirsle.net/apps/gophertype/pkg/settings"
|
|
|
|
redis "github.com/go-redis/redis/v8"
|
2021-05-31 23:11:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Global Redis configuration.
|
|
|
|
var (
|
2022-12-06 05:07:52 +00:00
|
|
|
RedisHost = "localhost"
|
|
|
|
RedisPort = 6379
|
|
|
|
RedisDB = 0
|
2021-05-31 23:11:01 +00:00
|
|
|
|
2022-12-06 05:07:52 +00:00
|
|
|
RedisClient *redis.Client
|
|
|
|
ready bool
|
2021-05-31 23:11:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Error codes
|
|
|
|
var (
|
2022-12-06 05:07:52 +00:00
|
|
|
ErrNotReady = errors.New("RedisClient not ready")
|
2021-05-31 23:11:01 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Connect to Redis after loading the details from the site's settings.json.
|
|
|
|
func Connect() error {
|
2022-12-06 05:07:52 +00:00
|
|
|
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")
|
2021-05-31 23:11:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SetEx sets a cache key with expiration.
|
|
|
|
func SetEx(key string, value string, exp int64) error {
|
2022-12-06 05:07:52 +00:00
|
|
|
if RedisClient == nil {
|
|
|
|
return ErrNotReady
|
|
|
|
}
|
2021-05-31 23:11:01 +00:00
|
|
|
|
2022-12-06 05:07:52 +00:00
|
|
|
err := RedisClient.Set(context.Background(), key, value, time.Duration(exp)*time.Second).Err()
|
|
|
|
return err
|
2021-05-31 23:11:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get a cache key.
|
|
|
|
func Get(key string) (string, error) {
|
2022-12-06 05:07:52 +00:00
|
|
|
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
|
|
|
|
}
|
2021-05-31 23:11:01 +00:00
|
|
|
|
2022-12-06 05:07:52 +00:00
|
|
|
// Delete a key from Redis.
|
|
|
|
func Delete(key string) error {
|
|
|
|
return RedisClient.Del(context.Background(), key).Err()
|
2021-05-31 23:11:01 +00:00
|
|
|
}
|