package adapter import ( "bytes" "context" "encoding/gob" "errors" "fmt" "time" "ariga.io/entcache" "github.com/redis/go-redis/v9" ) type RedisCache struct { redis *redis.ClusterClient } func NewRedisCache(redis *redis.ClusterClient) *RedisCache { return &RedisCache{redis: redis} } func (c *RedisCache) Del(ctx context.Context, key entcache.Key) error { if k, ok := key.(string); !ok { return fmt.Errorf("key is not a string") } else { c.redis.Del(ctx, k) return nil } } func (c *RedisCache) Add(ctx context.Context, key entcache.Key, entry *entcache.Entry, duration time.Duration) error { k, ok := key.(string) if !ok { return fmt.Errorf("key is not a string") } var buf bytes.Buffer if err := gob.NewEncoder(&buf).Encode(entry); err != nil { return fmt.Errorf("failed to encode entry: %w", err) } return c.redis.Set(ctx, k, buf.Bytes(), duration).Err() } func (c *RedisCache) Get(ctx context.Context, key entcache.Key) (*entcache.Entry, error) { k, ok := key.(string) if !ok { return nil, fmt.Errorf("key is not a string") } val, err := c.redis.Get(ctx, k).Bytes() if err != nil { if errors.Is(err, redis.Nil) { // 缓存未命中 return nil, nil } return nil, err } var entry entcache.Entry if err := gob.NewDecoder(bytes.NewReader(val)).Decode(&entry); err != nil { return nil, fmt.Errorf("failed to decode entry: %w", err) } return &entry, nil }