feat(chat): implement sequence pre-allocation, versioned sync, and push worker
Introduce several performance and synchronization enhancements: - Implement `SeqBufferManager` to allow sequence number pre-allocation via Redis Lua scripts, reducing atomic increment overhead. - Add `PushWorker` to handle asynchronous message pushing using Redis Streams. - Implement incremental conversation synchronization via `ConversationVersionLog` to allow clients to fetch only recent changes. - Add support for Gzip compression in WebSocket communications to reduce bandwidth usage. - Update dependency injection and configuration to support these new components.
This commit is contained in:
38
internal/cache/conversation_cache.go
vendored
38
internal/cache/conversation_cache.go
vendored
@@ -230,22 +230,24 @@ type MessageRepository interface {
|
||||
|
||||
// ConversationCache 会话缓存管理器
|
||||
type ConversationCache struct {
|
||||
cache Cache // 底层缓存
|
||||
settings *ConversationCacheSettings // 配置
|
||||
repo ConversationRepository // 数据仓库接口(用于 cache-aside 回源)
|
||||
msgRepo MessageRepository // 消息数据仓库接口(用于消息缓存回源)
|
||||
cache Cache // 底层缓存
|
||||
settings *ConversationCacheSettings // 配置
|
||||
repo ConversationRepository // 数据仓库接口(用于 cache-aside 回源)
|
||||
msgRepo MessageRepository // 消息数据仓库接口(用于消息缓存回源)
|
||||
seqBufferMgr *SeqBufferManager // seq 预分配管理器(nil 则使用旧 INCR 逻辑)
|
||||
}
|
||||
|
||||
// NewConversationCache 创建会话缓存管理器
|
||||
func NewConversationCache(cache Cache, repo ConversationRepository, msgRepo MessageRepository, settings *ConversationCacheSettings) *ConversationCache {
|
||||
func NewConversationCache(cache Cache, repo ConversationRepository, msgRepo MessageRepository, settings *ConversationCacheSettings, seqBufferMgr *SeqBufferManager) *ConversationCache {
|
||||
if settings == nil {
|
||||
settings = DefaultConversationCacheSettings()
|
||||
}
|
||||
return &ConversationCache{
|
||||
cache: cache,
|
||||
settings: settings,
|
||||
repo: repo,
|
||||
msgRepo: msgRepo,
|
||||
cache: cache,
|
||||
settings: settings,
|
||||
repo: repo,
|
||||
msgRepo: msgRepo,
|
||||
seqBufferMgr: seqBufferMgr,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,8 +696,16 @@ func (c *ConversationCache) ComputeAllUnreadCount(ctx context.Context, userID st
|
||||
}
|
||||
|
||||
// GetNextSeq 获取会话的下一个 seq 值(原子递增)
|
||||
// 使用 Redis INCR 实现,首次调用时从 DB 初始化并补齐差值
|
||||
// 启用 seq 预分配时使用本地缓冲区 + Redis Lua 分配;否则使用旧 INCR 逻辑
|
||||
func (c *ConversationCache) GetNextSeq(ctx context.Context, convID string) (int64, error) {
|
||||
// 优先使用 seq 预分配
|
||||
if c.seqBufferMgr != nil && c.seqBufferMgr.IsEnabled() {
|
||||
// 判断是否群聊(通过会话类型判断,这里先按私聊处理,由上层传入 isGroup)
|
||||
// 由于接口只传 convID,这里默认私聊逻辑,群聊的 isGroup 由调用方决定
|
||||
return c.seqBufferMgr.GetNextSeq(ctx, convID, false)
|
||||
}
|
||||
|
||||
// 降级到旧 INCR 逻辑
|
||||
seqKey := MessageSeqKey(convID)
|
||||
|
||||
newSeq, err := c.cache.Incr(ctx, seqKey)
|
||||
@@ -732,6 +742,14 @@ func (c *ConversationCache) GetNextSeq(ctx context.Context, convID string) (int6
|
||||
return newSeq, nil
|
||||
}
|
||||
|
||||
// GetNextSeqWithGroup 获取会话的下一个 seq 值(支持群聊标识,用于 seq 预分配步长区分)
|
||||
func (c *ConversationCache) GetNextSeqWithGroup(ctx context.Context, convID string, isGroup bool) (int64, error) {
|
||||
if c.seqBufferMgr != nil && c.seqBufferMgr.IsEnabled() {
|
||||
return c.seqBufferMgr.GetNextSeq(ctx, convID, isGroup)
|
||||
}
|
||||
return c.GetNextSeq(ctx, convID)
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 消息缓存方法
|
||||
// ============================================================
|
||||
|
||||
Reference in New Issue
Block a user