1
This commit is contained in:
139
common/helper/cache_helper.go
Normal file
139
common/helper/cache_helper.go
Normal file
@ -0,0 +1,139 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/bytedance/sonic"
|
||||
"github.com/go-redis/redis/v8"
|
||||
)
|
||||
|
||||
// CacheFunction 通用缓存装饰器,支持任意函数类型
|
||||
func CacheFunctionExpire[T any](fn func(args ...any) (T, error), keyPrefix string, ttl time.Duration) func(args ...any) (T, error) {
|
||||
return func(args ...any) (T, error) {
|
||||
// 创建缓存键,基于函数名和参数
|
||||
cacheKey := fmt.Sprintf("%s:%v", keyPrefix, args)
|
||||
|
||||
// 尝试从 Redis 获取缓存
|
||||
cachedData, err := DefaultRedis.GetString(cacheKey)
|
||||
var zeroT T // 用于返回零值
|
||||
if err == redis.Nil {
|
||||
// 缓存不存在,调用实际函数
|
||||
result, err := fn(args...)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
// 将结果序列化并存入 Redis
|
||||
jsonData, err := sonic.Marshal(result)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
err = DefaultRedis.SetStringExpire(cacheKey, string(jsonData), ttl)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
} else if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
// 缓存命中,反序列化结果
|
||||
var result T
|
||||
err = sonic.Unmarshal([]byte(cachedData), &result)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// CacheFunction 通用缓存装饰器,支持任意函数类型
|
||||
func CacheFunctionNoArgsExpire[T any](fn func() (T, error), keyPrefix string, ttl time.Duration) func() (T, error) {
|
||||
return func() (T, error) {
|
||||
// 创建缓存键,基于函数名和参数
|
||||
cacheKey := keyPrefix
|
||||
|
||||
// 尝试从 Redis 获取缓存
|
||||
cachedData, err := DefaultRedis.GetString(cacheKey)
|
||||
var zeroT T // 用于返回零值
|
||||
if err == redis.Nil {
|
||||
// 缓存不存在,调用实际函数
|
||||
result, err := fn()
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
// 将结果序列化并存入 Redis
|
||||
jsonData, err := sonic.Marshal(result)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
err = DefaultRedis.SetStringExpire(cacheKey, string(jsonData), ttl)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
} else if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
// 缓存命中,反序列化结果
|
||||
var result T
|
||||
err = sonic.Unmarshal([]byte(cachedData), &result)
|
||||
if err != nil {
|
||||
return zeroT, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteCacheFunction 通用删除缓存装饰器
|
||||
func DeleteCacheFunction[T any](fn func(args ...any) (T, error), keyPrefix string) func(args ...any) (T, error) {
|
||||
return func(args ...any) (T, error) {
|
||||
// 调用实际函数
|
||||
result, err := fn(args...)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// 创建缓存键,基于函数名和参数
|
||||
cacheKey := fmt.Sprintf("%s:%v", keyPrefix, args)
|
||||
|
||||
// 从 Redis 删除缓存
|
||||
err = DefaultRedis.DeleteString(cacheKey)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to delete cache: %w", err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteCacheFunction 通用删除缓存装饰器
|
||||
func DeleteCacheNoArgsFunction[T any](fn func() (T, error), keyPrefix string) func() (T, error) {
|
||||
return func() (T, error) {
|
||||
// 调用实际函数
|
||||
result, err := fn()
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
// 创建缓存键,基于函数名和参数
|
||||
cacheKey := keyPrefix
|
||||
|
||||
// 从 Redis 删除缓存
|
||||
err = DefaultRedis.DeleteString(cacheKey)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to delete cache: %w", err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user