topfans/backend/services/statisticService/service/cache.go
2026-07-03 14:57:14 +08:00

84 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/redis/go-redis/v9"
)
// Cache Redis 缓存封装5min TTL + 1min 空值 TTL 防穿透)
type Cache struct {
rdb *redis.Client
ttl time.Duration
emptyTTL time.Duration
missedHits int64
}
// NewCache 构造
func NewCache(rdb *redis.Client) *Cache {
return &Cache{
rdb: rdb,
ttl: 5 * time.Minute,
emptyTTL: 1 * time.Minute,
}
}
// GetJSON 取缓存 + JSON 反序列化
func (c *Cache) GetJSON(ctx context.Context, key string, dst interface{}) (bool, error) {
v, err := c.rdb.Get(ctx, key).Result()
if err == redis.Nil {
return false, nil
}
if err != nil {
return false, err
}
if v == "null" {
return false, nil // 缓存穿透防护的空标记
}
if err := json.Unmarshal([]byte(v), dst); err != nil {
return false, err
}
return true, nil
}
// SetJSON 序列化 + 缓存5min TTL
func (c *Cache) SetJSON(ctx context.Context, key string, value interface{}) error {
b, err := json.Marshal(value)
if err != nil {
return err
}
return c.rdb.Set(ctx, key, b, c.ttl).Err()
}
// SetEmpty 缓存空值1min TTL防穿透
func (c *Cache) SetEmpty(ctx context.Context, key string) error {
return c.rdb.Set(ctx, key, "null", c.emptyTTL).Err()
}
// Delete 删除单个缓存 key
func (c *Cache) Delete(ctx context.Context, key string) error {
return c.rdb.Del(ctx, key).Err()
}
// DeleteDashboardCache 删除指定 (starID, userID) 的所有看板缓存
// 在事件落库后调用,确保下次看板请求能读到最新数据
func (c *Cache) DeleteDashboardCache(ctx context.Context, starID, userID int64) error {
rpcKeys := []string{
"today_overview", "7day_income_curve", "exhibition_summary",
"like_income_by_level", "top_assets", "level_distribution", "upgrade_progress",
}
keys := make([]string, len(rpcKeys))
for i, rpc := range rpcKeys {
keys[i] = CacheKey(rpc, starID, userID)
}
return c.rdb.Del(ctx, keys...).Err()
}
// CacheKey 看板缓存 key 格式
func CacheKey(rpc string, starID, userID int64) string {
return fmt.Sprintf("dash:%s:%d:%d", rpc, starID, userID)
}