-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
cs-haproxy-spoa-bouncer/internal/session/root.go
Lines 159 to 201 in 3c6a8aa
func (s *Sessions) garbageCollect(ctx context.Context) { | |
s.logger.Debug("starting session garbage collection goroutine") | |
ticker := time.NewTicker(time.Duration(s.SessionGarbageSeconds) * time.Second) | |
defer ticker.Stop() | |
for { | |
select { | |
case <-ctx.Done(): | |
s.logger.Debug("stopping session garbage collection goroutine") | |
s.sessions = make(map[string]*Session) | |
return | |
case <-ticker.C: | |
s.logger.Trace("checking for sessions to garbage collect") | |
if len(s.sessions) == 0 { | |
s.logger.Trace("no sessions to garbage collect") | |
continue | |
} | |
s.mu.Lock() | |
expiredSessions := make([]string, 0) | |
for uuid, session := range s.sessions { | |
if session.HasTimedOut(s.parsedIdleTimeout) || session.HasMaxTime(s.parsedMaxTime) { | |
s.logger.Tracef("session %s has timed out or reached max time", uuid) | |
expiredSessions = append(expiredSessions, uuid) | |
} | |
} | |
for _, uuid := range expiredSessions { | |
delete(s.sessions, uuid) | |
} | |
s.mu.Unlock() | |
if len(expiredSessions) > 0 { | |
s.logger.Tracef("flushed %d sessions", len(expiredSessions)) | |
} else { | |
s.logger.Trace("no timed out sessions to garbage collect") | |
} | |
} | |
} | |
} |
Creating an issue to explore an idea, should we create a sweeping flush system. Sweeping flush means we have 2 timers one to sweep the map and mark the session to be deleted and another timer that triggers once enough have been GC'ed. Currently as it stands every tick on the GC timer the whole session for Host is locked to sweep and delete, it doesnt hurt the performance too much for lower end traffic sources, however, if you have alot of captchas / current sessions or misbehaving clients the GC can cause problems:
- Whole sessions map is locked, and cannot create new ones or read whilst GC'ing
Metadata
Metadata
Assignees
Labels
No labels