From f4515ce5e499d7bfb8d730765ebfda803eb9e115 Mon Sep 17 00:00:00 2001 From: hhs <386998068@qq.com> Date: Sun, 14 Jun 2026 17:54:33 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Phase=208.3=20=E2=80=94=20Session=20Man?= =?UTF-8?q?ager=20=E6=B3=A8=E5=85=A5=20MessageRepository=EF=BC=8CAppendMes?= =?UTF-8?q?sage=20=E5=90=AF=E7=94=A8=20Write-Through?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/session/memory.go | 33 ++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/backend/internal/session/memory.go b/backend/internal/session/memory.go index 2df0be3..be8da3c 100644 --- a/backend/internal/session/memory.go +++ b/backend/internal/session/memory.go @@ -10,6 +10,7 @@ import ( "github.com/hhs/camtalk/internal/logger" "github.com/hhs/camtalk/internal/models" + "github.com/hhs/camtalk/internal/store" ) const ( @@ -33,11 +34,23 @@ type MemoryManager struct { ttl time.Duration maxHistory int stopCleaner chan struct{} + msgRepo store.MessageRepository // 可选,消息持久化(Write-Through) +} + +// Option MemoryManager 的函数式选项。 +type Option func(*MemoryManager) + +// WithMessageRepository 注入消息持久化仓库,启用 Write-Through 模式。 +func WithMessageRepository(repo store.MessageRepository) Option { + return func(m *MemoryManager) { + m.msgRepo = repo + } } // NewMemoryManager 创建内存版 SessionManager。 // ttl 为会话过期时间,maxHistory 为对话历史上限(0 表示使用默认值 20)。 -func NewMemoryManager(ttl time.Duration, maxHistory int) *MemoryManager { +// opts 为可选配置,如 WithMessageRepository 启用消息持久化。 +func NewMemoryManager(ttl time.Duration, maxHistory int, opts ...Option) *MemoryManager { if ttl <= 0 { ttl = defaultTTL } @@ -52,6 +65,10 @@ func NewMemoryManager(ttl time.Duration, maxHistory int) *MemoryManager { stopCleaner: make(chan struct{}), } + for _, opt := range opts { + opt(m) + } + // 启动后台清理 goroutine,每分钟清除过期会话。 go m.cleanLoop() @@ -242,12 +259,13 @@ func (m *MemoryManager) GetHistory(_ context.Context, sessionID string, limit in } // AppendMessage 追加一条对话消息,同时刷新 TTL。 +// 若配置了 MessageRepository,消息会异步写入 PostgreSQL(Write-Through)。 func (m *MemoryManager) AppendMessage(_ context.Context, sessionID string, msg models.Message) error { m.mu.Lock() - defer m.mu.Unlock() entry, ok := m.sessions[sessionID] if !ok || m.isExpired(entry) { + m.mu.Unlock() return ErrSessionNotFound } @@ -266,6 +284,17 @@ func (m *MemoryManager) AppendMessage(_ context.Context, sessionID string, msg m now := time.Now() entry.lastActive = now entry.session.UpdatedAt = now + m.mu.Unlock() + + // Write-Through:异步写冷存储,不阻塞调用方 + if m.msgRepo != nil { + go func() { + if err := m.msgRepo.SaveMessage(context.Background(), sessionID, msg, 0); err != nil { + logger.Log.Warnw("persist message failed", "session", sessionID, "error", err) + } + }() + } + return nil }