Shinwayy / internal /cache /response_cache_redis.go
Shinway Deploy
track binary files with git-lfs
db492de
Raw
History Blame Contribute Delete
1.99 kB
package cache
import (
"context"
"time"
json "github.com/goccy/go-json"
"github.com/redis/go-redis/v9"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
log "github.com/sirupsen/logrus"
)
type redisResponseCache struct {
cfg config.ResponseCacheConfig
client redis.UniversalClient
prefix string
stats responseCacheStats
}
func newRedisResponseCache(cfg config.ResponseCacheConfig, client redis.UniversalClient) *redisResponseCache {
prefix := cfg.RedisKeyPrefix
if prefix == "" {
prefix = "respcache"
}
return &redisResponseCache{
cfg: cfg,
client: client,
prefix: "cliproxy:" + prefix,
}
}
func (r *redisResponseCache) Get(ctx context.Context, key string) (*CachedResponse, bool) {
data, err := r.client.Get(ctx, r.formatKey(key)).Bytes()
if err != nil {
r.stats.recordMiss()
return nil, false
}
var entry CachedResponse
if err := json.Unmarshal(data, &entry); err != nil {
log.Warnf("response cache: unmarshal error: %v", err)
r.stats.recordMiss()
return nil, false
}
r.stats.recordHit()
return &entry, true
}
func (r *redisResponseCache) Set(ctx context.Context, key string, resp *CachedResponse, ttl time.Duration) error {
data, err := json.Marshal(resp)
if err != nil {
return err
}
return r.client.Set(ctx, r.formatKey(key), data, ttl).Err()
}
func (r *redisResponseCache) Delete(ctx context.Context, pattern string) error {
fullPattern := r.prefix + ":" + pattern
var cursor uint64
for {
keys, next, err := r.client.Scan(ctx, cursor, fullPattern, 100).Result()
if err != nil {
return err
}
if len(keys) > 0 {
r.client.Del(ctx, keys...)
}
cursor = next
if cursor == 0 {
break
}
}
return nil
}
func (r *redisResponseCache) Stats() CacheStats {
return CacheStats{
Hits: r.stats.hits.Load(),
Misses: r.stats.misses.Load(),
}
}
func (r *redisResponseCache) Close() error {
return nil
}
func (r *redisResponseCache) formatKey(key string) string {
return r.prefix + ":" + key
}