blog/jsondb/caches/redis/redis.go

110 lines
2.2 KiB
Go

package redis
import (
"encoding/json"
"fmt"
"time"
"github.com/garyburd/redigo/redis"
)
// Redis is a cache backend.
type Redis struct {
pool *redis.Pool
prefix string
}
// New Redis backend.
func New(address string, db int, prefix string) (*Redis, error) {
r := &Redis{
prefix: prefix,
pool: &redis.Pool{
MaxIdle: 3,
IdleTimeout: 240 * time.Second,
Dial: func() (redis.Conn, error) {
return redis.Dial("tcp", address,
redis.DialConnectTimeout(10*time.Second),
redis.DialDatabase(db),
redis.DialKeepAlive(30*time.Second),
)
},
},
}
return r, nil
}
// Get a key from Redis.
func (r *Redis) Get(key string) ([]byte, error) {
conn := r.pool.Get()
n, err := redis.Bytes(conn.Do("GET", r.prefix+key))
if err != nil {
return nil, fmt.Errorf("Redis SET error: %s (conn error: %s)", err, conn.Err())
}
return n, err
}
// GetJSON gets a JSON value from a Redis key.
func (r *Redis) GetJSON(key string, v any) error {
val, err := r.Get(key)
if err != nil {
return err
}
return json.Unmarshal(val, v)
}
// Set a key in Redis.
func (r *Redis) Set(key string, v []byte, expires int) error {
conn := r.pool.Get()
_, err := conn.Do("SETEX", r.prefix+key, expires, v)
if err != nil {
return fmt.Errorf("Redis SET error: %s (conn error: %s)", err, conn.Err())
}
return nil
}
// SetJSON sets a JSON encoded value into a Redis key.
func (r *Redis) SetJSON(key string, v any, expires int) error {
bin, err := json.Marshal(v)
if err != nil {
return err
}
return r.Set(key, bin, expires)
}
// Delete keys from Redis.
func (r *Redis) Delete(key ...string) {
conn := r.pool.Get()
for _, v := range key {
conn.Send("DEL", v)
}
conn.Flush()
conn.Receive()
}
// Keys returns a list of Redis keys matching a pattern.
func (r *Redis) Keys(pattern string) ([]string, error) {
conn := r.pool.Get()
n, err := redis.Strings(conn.Do("KEYS", pattern))
return n, err
}
// Lock a mutex.
func (r *Redis) Lock(key, value string, expires int) bool {
conn := r.pool.Get()
n, err := redis.Int(conn.Do("SETNX", r.prefix+key, value))
return err == nil && n == 1
}
// Unlock a mutex.
func (r *Redis) Unlock(key string) {
r.Delete(key)
}