feat(lyra)!: 接入 Redis 并添加缓存连通性实验
- 封装缓存读写、JSON 编解码、过期时间与操作超时 - 集中组装 Redis 依赖,在测试接口验证分类缓存读写 - 更新依赖并移除原 handler 测试 BREAKING CHANGE: 配置节由 redis 改为 cache,新增 db 和 timeout 配置项
This commit is contained in:
+68
@@ -0,0 +1,68 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json/v2"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
)
|
||||
|
||||
type Entry[T any] struct {
|
||||
Key string
|
||||
Value T
|
||||
TTL time.Duration
|
||||
}
|
||||
|
||||
type Cache struct {
|
||||
client *redis.Client
|
||||
operationTimeout time.Duration
|
||||
}
|
||||
|
||||
func NewCache(client *redis.Client, timeout time.Duration) *Cache {
|
||||
return &Cache{
|
||||
client: client,
|
||||
operationTimeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Cache) Get[T any](ctx context.Context, key string) (T, bool, error) {
|
||||
var zero T
|
||||
operationCtx, cancel := context.WithTimeout(ctx, c.operationTimeout)
|
||||
defer cancel()
|
||||
|
||||
payload, err := c.client.Get(operationCtx, key).Result()
|
||||
cancel()
|
||||
if errors.Is(err, redis.Nil) {
|
||||
return zero, false, nil
|
||||
}
|
||||
if err != nil {
|
||||
return zero, false, fmt.Errorf("读取缓存失败:%w", err)
|
||||
}
|
||||
var value T
|
||||
if err := json.Unmarshal([]byte(payload), &value); err != nil {
|
||||
return zero, false, fmt.Errorf("缓存解码失败:%w", err)
|
||||
}
|
||||
return value, true, nil
|
||||
}
|
||||
|
||||
func (c *Cache) Set[T any](ctx context.Context, entry Entry[T]) error {
|
||||
if entry.TTL < 0 {
|
||||
return fmt.Errorf("缓存过期时间必须大于等于零: %v", entry.TTL)
|
||||
}
|
||||
if err := ctx.Err(); err != nil {
|
||||
return fmt.Errorf("写入缓存失败:%w", err)
|
||||
}
|
||||
payload, err := json.Marshal(entry.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("缓存编码失败:%w", err)
|
||||
}
|
||||
operationCtx, cancel := context.WithTimeout(ctx, c.operationTimeout)
|
||||
defer cancel()
|
||||
if err := c.client.Set(operationCtx, entry.Key, payload, entry.TTL).Err(); err != nil {
|
||||
return fmt.Errorf("写入缓存失败:%w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user