This commit is contained in:
95
internal/session/store.go
Normal file
95
internal/session/store.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"kubeviz/internal/model"
|
||||
)
|
||||
|
||||
type sessionData struct {
|
||||
Dataset *model.Dataset
|
||||
LastAccess time.Time
|
||||
}
|
||||
|
||||
type Store struct {
|
||||
mu sync.RWMutex
|
||||
sessions map[string]*sessionData
|
||||
ttl time.Duration
|
||||
stopCh chan struct{}
|
||||
}
|
||||
|
||||
func NewStore(ttl time.Duration) *Store {
|
||||
s := &Store{
|
||||
sessions: make(map[string]*sessionData),
|
||||
ttl: ttl,
|
||||
stopCh: make(chan struct{}),
|
||||
}
|
||||
go s.cleanupLoop()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Store) Stop() {
|
||||
close(s.stopCh)
|
||||
}
|
||||
|
||||
func (s *Store) NewSessionID() (string, error) {
|
||||
buf := make([]byte, 16)
|
||||
if _, err := rand.Read(buf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(buf), nil
|
||||
}
|
||||
|
||||
func (s *Store) GetDataset(sessionID string) *model.Dataset {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
entry, ok := s.sessions[sessionID]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
entry.LastAccess = time.Now()
|
||||
return entry.Dataset
|
||||
}
|
||||
|
||||
func (s *Store) SetDataset(sessionID string, ds *model.Dataset) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.sessions[sessionID] = &sessionData{Dataset: ds, LastAccess: time.Now()}
|
||||
}
|
||||
|
||||
func (s *Store) Clear(sessionID string) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
delete(s.sessions, sessionID)
|
||||
}
|
||||
|
||||
func (s *Store) cleanupLoop() {
|
||||
ticker := time.NewTicker(1 * time.Minute)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-s.stopCh:
|
||||
return
|
||||
case <-ticker.C:
|
||||
s.cleanupExpired()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Store) cleanupExpired() {
|
||||
if s.ttl <= 0 {
|
||||
return
|
||||
}
|
||||
cutoff := time.Now().Add(-s.ttl)
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
for id, sess := range s.sessions {
|
||||
if sess.LastAccess.Before(cutoff) {
|
||||
delete(s.sessions, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user