140 lines
3.3 KiB
Go
140 lines
3.3 KiB
Go
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
|
|
}
|
|
}
|