69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
// Package redis adapts go-redis's pooled client to cache.Store.
|
|
package redis
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.yuntuo.hk/k2safe/go-omni/cache"
|
|
goredis "github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// Store borrows the client; its owner must close the client after users stop.
|
|
type Store struct {
|
|
client goredis.Cmdable
|
|
prefix string
|
|
}
|
|
|
|
func New(client goredis.Cmdable, prefix string) (*Store, error) {
|
|
if client == nil || len(prefix) > 1024 || strings.ContainsAny(prefix, "\r\n") {
|
|
return nil, errors.New("cache/redis: invalid client or prefix")
|
|
}
|
|
return &Store{client: client, prefix: prefix}, nil
|
|
}
|
|
|
|
func (s *Store) Get(ctx context.Context, key string) ([]byte, error) {
|
|
if err := cache.Check(ctx, key, 0); err != nil {
|
|
return nil, err
|
|
}
|
|
value, err := s.client.Get(ctx, s.prefix+key).Bytes()
|
|
if errors.Is(err, goredis.Nil) {
|
|
return nil, cache.ErrMiss
|
|
}
|
|
return value, err
|
|
}
|
|
|
|
func (s *Store) Set(ctx context.Context, key string, value []byte, ttl time.Duration) error {
|
|
if err := cache.Check(ctx, key, ttl); err != nil {
|
|
return err
|
|
}
|
|
// Redis expiration precision is milliseconds; round up, never truncate a
|
|
// positive duration to an unbounded lifetime.
|
|
if ttl > 0 && ttl < time.Millisecond {
|
|
ttl = time.Millisecond
|
|
}
|
|
return s.client.Set(ctx, s.prefix+key, value, ttl).Err()
|
|
}
|
|
|
|
func (s *Store) Delete(ctx context.Context, keys ...string) error {
|
|
if ctx == nil {
|
|
return errors.New("cache/redis: nil context")
|
|
}
|
|
if err := ctx.Err(); err != nil {
|
|
return err
|
|
}
|
|
names := make([]string, len(keys))
|
|
for i, key := range keys {
|
|
if err := cache.Check(ctx, key, 0); err != nil {
|
|
return err
|
|
}
|
|
names[i] = s.prefix + key
|
|
}
|
|
if len(names) == 0 {
|
|
return nil
|
|
}
|
|
return s.client.Del(ctx, names...).Err()
|
|
}
|