feat(cache): 添加复合键缓存操作支持

添加了基于 uint32+string 组合键的缓存操作方法,包括
GetByCompoundKey、SetByCompoundKey、DelByCompoundKey 和
ContainsByCompoundKey 方法,用于处理用户ID和会话ID的组合缓存场景

fix(vscode): 添加 cSpell 配置支持 struc 词汇

refactor(session): 移除过时的会话管理方法

移除了基于单一字符串键的会话管理方法,因为已迁移到使用
复合键的缓存操作方式
```
This commit is contained in:
昔念
2026-01-19 18:51:56 +08:00
parent 08ebf849eb
commit 026689f3ed
120 changed files with 1428 additions and 629 deletions

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"regexp"
"strconv"
"strings"
"time"
@@ -26,12 +27,17 @@ type cacheStore[T any] struct {
prefix string // 缓存键前缀
}
// 生成带前缀的缓存键
// 生成带前缀的缓存键 - 为普通字符串键使用
func (s *cacheStore[T]) formatKey(key string) string {
return s.prefix + strings.TrimSpace(key)
}
// Get 通过键获取缓存值
// 生成带前缀的复合缓存键 - 为 uint32+string 组合使用
func (s *cacheStore[T]) formatCompoundKey(userID uint32, sessionID string) string {
return s.prefix + strconv.FormatUint(uint64(userID), 10) + ":" + strings.TrimSpace(sessionID)
}
// Get 通过键获取缓存值 - 原始方法保持兼容性
func (s *cacheStore[T]) Get(ctx context.Context, key string) (T, error) {
var zero T
result, err := s.manager.Get(ctx, s.formatKey(key))
@@ -58,7 +64,35 @@ func (s *cacheStore[T]) Get(ctx context.Context, key string) (T, error) {
return converted, nil
}
// Set 设置缓存值并带有效期
// GetByCompoundKey 通过 uint32+string 组合键获取缓存值
func (s *cacheStore[T]) GetByCompoundKey(ctx context.Context, userID uint32, sessionID string) (T, error) {
var zero T
key := s.formatCompoundKey(userID, sessionID)
result, err := s.manager.Get(ctx, key)
if err != nil {
return zero, gerror.Wrapf(err, "获取缓存失败,键: %s", key)
}
if result.IsEmpty() {
return zero, ErrCacheMiss
}
// 使用 ConvertWithRefer 进行类型转换
value := gconv.ConvertWithRefer(result.Val(), zero)
// 类型断言检查转换结果
converted, ok := value.(T)
if !ok {
return zero, gerror.Wrapf(
ErrTypeConvert,
"键: %s缓存值实际类型: %T期望类型: %T",
key, result.Val(), zero,
)
}
return converted, nil
}
// Set 设置缓存值并带有效期 - 原始方法保持兼容性
func (s *cacheStore[T]) Set(ctx context.Context, key string, value T, duration time.Duration) error {
err := s.manager.Set(ctx, s.formatKey(key), value, duration)
if err != nil {
@@ -69,7 +103,19 @@ func (s *cacheStore[T]) Set(ctx context.Context, key string, value T, duration t
return nil
}
// Del 删除缓存
// SetByCompoundKey 通过 uint32+string 组合键设置缓存
func (s *cacheStore[T]) SetByCompoundKey(ctx context.Context, userID uint32, sessionID string, value T, duration time.Duration) error {
key := s.formatCompoundKey(userID, sessionID)
err := s.manager.Set(ctx, key, value, duration)
if err != nil {
return gerror.Wrapf(err, "设置缓存失败,键: %s值: %v", key, value)
}
fmt.Printf("[INFO] 缓存操作 [%s] 键: %d:%s 值: %v 有效期: %v\n",
s.prefix, userID, sessionID, value, duration)
return nil
}
// Del 删除缓存 - 原始方法保持兼容性
func (s *cacheStore[T]) Del(ctx context.Context, key string) error {
_, err := s.manager.Remove(ctx, s.formatKey(key))
if err != nil {
@@ -79,7 +125,18 @@ func (s *cacheStore[T]) Del(ctx context.Context, key string) error {
return nil
}
// Contains 检查缓存是否存在
// DelByCompoundKey 通过 uint32+string 组合键删除缓存
func (s *cacheStore[T]) DelByCompoundKey(ctx context.Context, userID uint32, sessionID string) error {
key := s.formatCompoundKey(userID, sessionID)
_, err := s.manager.Remove(ctx, key)
if err != nil {
return gerror.Wrapf(err, "删除缓存失败,键: %s", key)
}
fmt.Printf("[INFO] 删除缓存 [%s] 键: %d:%s 成功\n", s.prefix, userID, sessionID)
return nil
}
// Contains 检查缓存是否存在 - 原始方法保持兼容性
func (s *cacheStore[T]) Contains(ctx context.Context, key string) (bool, error) {
exists, err := s.manager.Contains(ctx, s.formatKey(key))
if err != nil {
@@ -88,6 +145,16 @@ func (s *cacheStore[T]) Contains(ctx context.Context, key string) (bool, error)
return exists, nil
}
// ContainsByCompoundKey 检查 uint32+string 组合键的缓存是否存在
func (s *cacheStore[T]) ContainsByCompoundKey(ctx context.Context, userID uint32, sessionID string) (bool, error) {
key := s.formatCompoundKey(userID, sessionID)
exists, err := s.manager.Contains(ctx, key)
if err != nil {
return false, gerror.Wrapf(err, "检查缓存是否存在失败,键: %s", key)
}
return exists, nil
}
// GetOrSet 获取缓存值,如果不存在则设置默认值
func (s *cacheStore[T]) GetOrSet(ctx context.Context, key string, defaultValue T, duration time.Duration) (T, error) {
var zero T

View File

@@ -51,26 +51,6 @@ func newSessionManager() *sessionManager {
}
}
// GetSession 通过会话ID获取用户ID
func (m *sessionManager) GetSession(sessionID string) (uint32, error) {
return m.sessionStore.Get(context.Background(), sessionID)
}
// SaveSession 保存会话信息
func (m *sessionManager) SaveSession(sessionID string, userID uint32) error {
return m.sessionStore.Set(gctx.New(), sessionID, userID, time.Hour*1)
}
// DeleteSession 删除会话
func (m *sessionManager) DeleteSession(sessionID string) error {
return m.sessionStore.Del(gctx.New(), sessionID)
}
// SessionExists 检查会话是否存在
func (m *sessionManager) SessionExists(sessionID string) (bool, error) {
return m.sessionStore.Contains(context.Background(), sessionID)
}
// SetUserOnline 设置用户在线状态
func (m *sessionManager) SetUserOnline(userID uint32, serverID uint16) error {
return m.userOnlineStore.Set(gctx.New(), gconv.String(userID), serverID, 0)

File diff suppressed because one or more lines are too long