Files
Sotig 0c40983293 ui
2026-05-29 21:16:10 +03:00

62 lines
1.7 KiB
Go

package cache
import (
"context"
"time"
"github.com/redis/go-redis/v9"
)
// Cache is a minimal interface for key/value byte storage with TTL.
// Both the Valkey implementation and the no-op satisfy it.
type Cache interface {
Get(ctx context.Context, key string) ([]byte, bool)
Set(ctx context.Context, key string, value []byte, ttl time.Duration)
}
// valkeyCache wraps a go-redis client connected to a Valkey (or Redis) server.
type valkeyCache struct {
client *redis.Client
}
// NewValkeyCache parses url (e.g. "redis://localhost:6379"), pings the server,
// and returns a ready Cache. Returns an error if the server is unreachable.
func NewValkeyCache(url string) (Cache, error) {
opts, err := redis.ParseURL(url)
if err != nil {
return nil, err
}
client := redis.NewClient(opts)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := client.Ping(ctx).Err(); err != nil {
client.Close()
return nil, err
}
return &valkeyCache{client: client}, nil
}
func (c *valkeyCache) Get(ctx context.Context, key string) ([]byte, bool) {
val, err := c.client.Get(ctx, key).Bytes()
if err != nil {
return nil, false
}
return val, true
}
func (c *valkeyCache) Set(ctx context.Context, key string, value []byte, ttl time.Duration) {
// Best-effort: cache errors are non-fatal.
c.client.Set(ctx, key, value, ttl)
}
// noopCache is used when VALKEY_URL is not configured.
// All Gets miss; all Sets are discarded.
type noopCache struct{}
// NewNoopCache returns a Cache that never stores anything.
func NewNoopCache() Cache { return &noopCache{} }
func (c *noopCache) Get(_ context.Context, _ string) ([]byte, bool) { return nil, false }
func (c *noopCache) Set(_ context.Context, _ string, _ []byte, _ time.Duration) {
}