fix: correct grace period protection during primary reconnection

- Remove broken bypass logic that caused immediate observer promotion on refresh
- Add session map debugging logs to validateSinglePrimary
- Ensure grace period properly blocks auto-promotion until expiration
This commit is contained in:
Alex P 2025-10-08 23:58:27 +03:00
parent f9ebd6ac2f
commit 541d2bd77d
1 changed files with 16 additions and 24 deletions

View File

@ -888,6 +888,17 @@ func (sm *SessionManager) UpdateLastActive(sessionID string) {
func (sm *SessionManager) validateSinglePrimary() { func (sm *SessionManager) validateSinglePrimary() {
primarySessions := make([]*Session, 0) primarySessions := make([]*Session, 0)
sm.logger.Debug().
Int("sm.sessions_len", len(sm.sessions)).
Interface("sm.sessions_keys", func() []string {
keys := make([]string, 0, len(sm.sessions))
for k := range sm.sessions {
keys = append(keys, k)
}
return keys
}()).
Msg("validateSinglePrimary: checking sm.sessions map")
// Find all sessions that think they're primary // Find all sessions that think they're primary
for _, session := range sm.sessions { for _, session := range sm.sessions {
if session.Mode == SessionModePrimary { if session.Mode == SessionModePrimary {
@ -952,35 +963,16 @@ func (sm *SessionManager) validateSinglePrimary() {
} }
// Check if there's an active grace period for any primary session // Check if there's an active grace period for any primary session
// BUT: if grace period just started (within 2 seconds), allow immediate promotion
hasActivePrimaryGracePeriod := false hasActivePrimaryGracePeriod := false
for sessionID, graceTime := range sm.reconnectGrace { for sessionID, graceTime := range sm.reconnectGrace {
if time.Now().Before(graceTime) { if time.Now().Before(graceTime) {
if reconnectInfo, hasInfo := sm.reconnectInfo[sessionID]; hasInfo { if reconnectInfo, hasInfo := sm.reconnectInfo[sessionID]; hasInfo {
if reconnectInfo.Mode == SessionModePrimary { if reconnectInfo.Mode == SessionModePrimary {
// Calculate how long ago the grace period started hasActivePrimaryGracePeriod = true
gracePeriod := 10 sm.logger.Debug().
if currentSessionSettings != nil && currentSessionSettings.ReconnectGrace > 0 { Str("gracePrimaryID", sessionID).
gracePeriod = currentSessionSettings.ReconnectGrace Dur("remainingGrace", time.Until(graceTime)).
} Msg("Active grace period detected for primary session - blocking auto-promotion")
graceStartTime := graceTime.Add(-time.Duration(gracePeriod) * time.Second)
timeSinceGraceStart := time.Since(graceStartTime)
// If grace period just started (within 2 seconds), allow immediate promotion
// This enables instant promotion on logout while still protecting against network blips
if timeSinceGraceStart > 2*time.Second {
hasActivePrimaryGracePeriod = true
sm.logger.Debug().
Str("gracePrimaryID", sessionID).
Dur("remainingGrace", time.Until(graceTime)).
Dur("timeSinceGraceStart", timeSinceGraceStart).
Msg("Active grace period detected for primary session - blocking auto-promotion")
} else {
sm.logger.Debug().
Str("gracePrimaryID", sessionID).
Dur("timeSinceGraceStart", timeSinceGraceStart).
Msg("Grace period just started - allowing immediate promotion")
}
break break
} }
} }