-
Notifications
You must be signed in to change notification settings - Fork 0
/
cache.go
71 lines (61 loc) · 1.66 KB
/
cache.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package redis_cache
import (
"context"
"encoding/json"
"errors"
"github.com/redis/go-redis/v9"
)
type QueryFunc[T any] func() (T, error)
// QueryWithCache 带着缓存查询
// model,传出参数,数据模型
// query,查询函数,缓存未命中时调用
// return,是否命中缓存
func QueryWithCache[T any](rdb redis.UniversalClient, key string, model *T, query QueryFunc[*T], options ...Option) (bool, error) {
// 获取缓存配置
config := CacheConfig{
cacheTime: DefaultCacheTime,
diff: DefaultCacheTimeDiff,
ctx: context.Background(),
flush: false,
write: true,
}
for _, opt := range options {
opt(&config)
}
data, err := rdb.Get(config.ctx, key).Result()
if err == nil {
// 命中缓存
err = json.Unmarshal([]byte(data), model)
if err != nil {
// json解析出错,以未命中缓存处理
return false, cacheMiss(rdb, key, model, query, &config)
}
// 刷新缓存时间
if config.flush {
return true, rdb.Expire(config.ctx, key, computeCacheTime(config.cacheTime, config.diff)).Err()
}
return true, nil
} else if errors.Is(err, redis.Nil) {
// 未命中缓存
return false, cacheMiss(rdb, key, model, query, &config)
}
// 出现错误
return false, err
}
// 缓存未命中
func cacheMiss[T any](rdb redis.UniversalClient, key string, model *T, query QueryFunc[*T], config *CacheConfig) error {
res, err := query()
if err != nil {
return err
}
*model = *res
// 不写入缓存
if !config.write {
return nil
}
data, err := json.Marshal(model)
if err != nil {
return err
}
return rdb.SetEx(config.ctx, key, string(data), computeCacheTime(config.cacheTime, config.diff)).Err()
}