From d162c32a574dc646d55cfb8c559b146a159a839f Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Mon, 8 Jun 2026 18:37:42 -0400 Subject: [PATCH] begin handling cleanup of session tokens --- src/session/session_manager.go | 24 ++++++++++++++++++++++- src/store/store_in_memory.go | 36 +++++++++++++++++----------------- 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/session/session_manager.go b/src/session/session_manager.go index 62d95af..627c78a 100644 --- a/src/session/session_manager.go +++ b/src/session/session_manager.go @@ -7,6 +7,7 @@ import ( "astraltech.xyz/accountmanager/src/logging" "astraltech.xyz/accountmanager/src/store" + "astraltech.xyz/accountmanager/src/worker" ) const SessionCookieName = "session_token" @@ -37,7 +38,11 @@ func (manager *SessionManager) SetStoreType(storeType StoreType) { switch storeType { case InMemory: { - // manager.store = NewMemoryStore() + manager.store = store.NewMemoryStore[*SessionData]() + worker.CreateWorker(time.Minute*5, func() { + inMemStore, _ := manager.store.(*store.MemoryStore[*SessionData]) + cleanupInMemoryStore(inMemStore) + }) break } case Redis: @@ -98,6 +103,23 @@ func (manager *SessionManager) GetSession(r *http.Request) (*SessionData, error) return data, nil } +func cleanupInMemoryStore(m *store.MemoryStore[*SessionData]) { + logging.Debug("Cleaning up memory store sessions") + now := time.Now() + + m.Lock.Lock() + defer m.Lock.Unlock() + + deleted := 0 + for id, session := range m.Sessions { + if now.After(session.ExpiresAt) { + delete(m.Sessions, id) + deleted = deleted + 1 + } + } + logging.Infof("Cleaned up %d stale sessions", deleted) +} + func (manager *SessionManager) DeleteSession(sessionId string) error { return manager.store.Delete(sessionId) } diff --git a/src/store/store_in_memory.go b/src/store/store_in_memory.go index 5687a1b..816cbaf 100644 --- a/src/store/store_in_memory.go +++ b/src/store/store_in_memory.go @@ -7,14 +7,14 @@ import ( ) type MemoryStore[Value any] struct { - sessions map[string]Value - lock sync.RWMutex + Sessions map[string]Value + Lock sync.RWMutex } func NewMemoryStore[Value any]() *MemoryStore[Value] { logging.Debug("Creating new in memory session store") store := &MemoryStore[Value]{ - sessions: make(map[string]Value), + Sessions: make(map[string]Value), } return store } @@ -22,24 +22,24 @@ func NewMemoryStore[Value any]() *MemoryStore[Value] { func (m *MemoryStore[Value]) Create(key string, session Value) (err error) { hashedkey := HashKey(key) - m.lock.Lock() - defer m.lock.Unlock() - _, exist := m.sessions[hashedkey] + m.Lock.Lock() + defer m.Lock.Unlock() + _, exist := m.Sessions[hashedkey] if exist { return ErrKeyAlreadyExists } - m.sessions[hashedkey] = session + m.Sessions[hashedkey] = session return nil } func (m *MemoryStore[Value]) Get(key string) (Value, error) { var data Value - m.lock.RLock() + m.Lock.RLock() hashedkey := HashKey(key) - data, exists := m.sessions[hashedkey] - m.lock.RUnlock() + data, exists := m.Sessions[hashedkey] + m.Lock.RUnlock() if exists == false { return data, ErrKeyNotFound } @@ -49,25 +49,25 @@ func (m *MemoryStore[Value]) Get(key string) (Value, error) { func (m *MemoryStore[Value]) Update(sessionID string, session Value) error { hashedkey := HashKey(sessionID) - m.lock.Lock() - defer m.lock.Unlock() - _, exist := m.sessions[hashedkey] + m.Lock.Lock() + defer m.Lock.Unlock() + _, exist := m.Sessions[hashedkey] if !exist { return ErrKeyNotFound } - m.sessions[hashedkey] = session + m.Sessions[hashedkey] = session return nil } func (m *MemoryStore[Value]) Delete(sessionID string) error { hashedkey := HashKey(sessionID) - m.lock.Lock() - defer m.lock.Unlock() - _, exist := m.sessions[hashedkey] + m.Lock.Lock() + defer m.Lock.Unlock() + _, exist := m.Sessions[hashedkey] if !exist { return ErrKeyNotFound } - delete(m.sessions, hashedkey) + delete(m.Sessions, hashedkey) return nil }