Files
cmr-mini/realtime-gateway/internal/session/session.go

110 lines
2.2 KiB
Go

package session
import (
"sync"
"sync/atomic"
"time"
"realtime-gateway/internal/model"
)
type Session struct {
ID string
Role model.Role
Authenticated bool
ChannelID string
Subscriptions []model.Subscription
CreatedAt time.Time
}
type Snapshot struct {
ID string `json:"id"`
Role model.Role `json:"role"`
Authenticated bool `json:"authenticated"`
ChannelID string `json:"channelId,omitempty"`
CreatedAt time.Time `json:"createdAt"`
Subscriptions []model.Subscription `json:"subscriptions"`
}
type Manager struct {
mu sync.RWMutex
sequence atomic.Uint64
sessions map[string]*Session
}
func NewManager() *Manager {
return &Manager{
sessions: make(map[string]*Session),
}
}
func (m *Manager) Create() *Session {
id := m.sequence.Add(1)
session := &Session{
ID: formatSessionID(id),
Role: model.RoleConsumer,
CreatedAt: time.Now(),
}
m.mu.Lock()
m.sessions[session.ID] = session
m.mu.Unlock()
return session
}
func (m *Manager) Delete(sessionID string) {
m.mu.Lock()
delete(m.sessions, sessionID)
m.mu.Unlock()
}
func (m *Manager) Get(sessionID string) (*Session, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
session, ok := m.sessions[sessionID]
return session, ok
}
func (m *Manager) Count() int {
m.mu.RLock()
defer m.mu.RUnlock()
return len(m.sessions)
}
func (m *Manager) List() []Snapshot {
m.mu.RLock()
defer m.mu.RUnlock()
snapshots := make([]Snapshot, 0, len(m.sessions))
for _, current := range m.sessions {
subscriptions := append([]model.Subscription(nil), current.Subscriptions...)
snapshots = append(snapshots, Snapshot{
ID: current.ID,
Role: current.Role,
Authenticated: current.Authenticated,
ChannelID: current.ChannelID,
CreatedAt: current.CreatedAt,
Subscriptions: subscriptions,
})
}
return snapshots
}
func formatSessionID(id uint64) string {
return "sess-" + itoa(id)
}
func itoa(v uint64) string {
if v == 0 {
return "0"
}
var buf [20]byte
i := len(buf)
for v > 0 {
i--
buf[i] = byte('0' + v%10)
v /= 10
}
return string(buf[i:])
}