aurora / internal /handler /session_manager.go
qwen2api's picture
Upload 113 files
6bc074c verified
Raw
History Blame Contribute Delete
1.69 kB
package handler
import (
"aurora/internal/chatgpt"
"log"
"sync"
"time"
)
// SessionManager 按 conversationID 缓存 ChatClientState,
// 使得同一对话的多轮请求复用相同的 DeviceID / SessionID。
type SessionManager struct {
mu sync.RWMutex
sessions map[string]*sessionEntry
ttl time.Duration
}
type sessionEntry struct {
state *chatgpt.ChatClientState
lastUsed time.Time
}
const defaultSessionTTL = 30 * time.Minute
func NewSessionManager() *SessionManager {
sm := &SessionManager{
sessions: make(map[string]*sessionEntry),
ttl: defaultSessionTTL,
}
go sm.cleanupLoop()
return sm
}
func (sm *SessionManager) Get(conversationID string) *chatgpt.ChatClientState {
if conversationID == "" {
return nil
}
sm.mu.RLock()
entry, ok := sm.sessions[conversationID]
sm.mu.RUnlock()
if !ok {
return nil
}
sm.mu.Lock()
entry.lastUsed = time.Now()
sm.mu.Unlock()
return entry.state
}
func (sm *SessionManager) Register(conversationID string, state *chatgpt.ChatClientState) {
if conversationID == "" || state == nil {
return
}
sm.mu.Lock()
defer sm.mu.Unlock()
sm.sessions[conversationID] = &sessionEntry{
state: state,
lastUsed: time.Now(),
}
}
func (sm *SessionManager) cleanupLoop() {
ticker := time.NewTicker(10 * time.Minute)
defer ticker.Stop()
for range ticker.C {
sm.mu.Lock()
now := time.Now()
removed := 0
for convID, entry := range sm.sessions {
if now.Sub(entry.lastUsed) > sm.ttl {
delete(sm.sessions, convID)
removed++
}
}
if removed > 0 {
log.Printf("[session] 清理过期 session %d 个,当前活跃 %d 个", removed, len(sm.sessions))
}
sm.mu.Unlock()
}
}