Files
kubeviz/internal/session/store.go
Clemens Hering 1a0bbe9dfd
Some checks failed
Deploy KubeViz / deploy (push) Has been cancelled
Teststand
2026-03-01 07:40:49 +01:00

96 lines
1.6 KiB
Go

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)
}
}
}