mirror of
https://github.com/ThisTine/Snip.git
synced 2026-08-18 23:18:47 +07:00
59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
// Package rediscache implements the LinkCache port on Redis. This is the layer
|
|
// that keeps the redirect hot path off Postgres.
|
|
package rediscache
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
|
|
"github.com/snip/backend/internal/port"
|
|
)
|
|
|
|
type Cache struct {
|
|
rdb *redis.Client
|
|
prefix string
|
|
}
|
|
|
|
func New(ctx context.Context, addr, password string, db int, keyPrefix string) (*Cache, error) {
|
|
rdb := redis.NewClient(&redis.Options{Addr: addr, Password: password, DB: db})
|
|
if err := rdb.Ping(ctx).Err(); err != nil {
|
|
_ = rdb.Close()
|
|
return nil, err
|
|
}
|
|
return &Cache{rdb: rdb, prefix: keyPrefix + "code:"}, nil
|
|
}
|
|
|
|
func (c *Cache) key(code string) string { return c.prefix + code }
|
|
|
|
func (c *Cache) GetResolution(ctx context.Context, code string) (port.Resolution, bool, error) {
|
|
b, err := c.rdb.Get(ctx, c.key(code)).Bytes()
|
|
if err == redis.Nil {
|
|
return port.Resolution{}, false, nil
|
|
}
|
|
if err != nil {
|
|
return port.Resolution{}, false, err
|
|
}
|
|
var r port.Resolution
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return port.Resolution{}, false, err
|
|
}
|
|
return r, true, nil
|
|
}
|
|
|
|
func (c *Cache) SetResolution(ctx context.Context, code string, r port.Resolution, ttl time.Duration) error {
|
|
b, err := json.Marshal(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return c.rdb.Set(ctx, c.key(code), b, ttl).Err()
|
|
}
|
|
|
|
func (c *Cache) Invalidate(ctx context.Context, code string) error {
|
|
return c.rdb.Del(ctx, c.key(code)).Err()
|
|
}
|
|
|
|
func (c *Cache) Close() error { return c.rdb.Close() }
|