gophertype/pkg/cache/redis.go
Noah Petherbridge 777fd85085 Dust off gophertype and fix some bugs
* Add a rate limiter to the login page.
* Fix the CSRF cookie expiring after 24 hours; it now will be a session
  cookie that expires on browser exit so you get a fresh one each visit.
* Remove the dependency on go-bindata and use native Go file embed
* Add documentation
2022-12-05 21:09:06 -08:00

91 lines
1.8 KiB
Go

// 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()
}