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
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 |