mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
fix(channelserver): eliminate data races in shutdown and session lifecycle
The channel server had several concurrency issues found by the race detector during isolation testing: - acceptClients could send on a closed acceptConns channel during shutdown, causing a panic. Replace close(acceptConns) with a done channel and select-based shutdown signaling in both acceptClients and manageSessions. - invalidateSessions read isShuttingDown and iterated sessions without holding the lock. Rewrite with ticker + done channel select and snapshot sessions under lock before processing timeouts. - sendLoop/recvLoop accessed global _config.ErupeConfig.LoopDelay which races with tests modifying the global. Use the per-server erupeConfig instead. - logoutPlayer panicked on DB errors and crashed on nil DB (no-db test scenarios). Guard with nil check and log errors instead. - Shutdown was not idempotent, double-calling caused double-close panic on done channel. Add 5 channel isolation tests verifying independent shutdown, listener failure, session panic recovery, cross-channel registry after shutdown, and stage isolation.
This commit is contained in:
@@ -293,14 +293,16 @@ func logoutPlayer(s *Session) {
|
||||
}
|
||||
|
||||
// Update sign sessions and server player count
|
||||
_, err := s.server.db.Exec("UPDATE sign_sessions SET server_id=NULL, char_id=NULL WHERE token=$1", s.token)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if s.server.db != nil {
|
||||
_, err := s.server.db.Exec("UPDATE sign_sessions SET server_id=NULL, char_id=NULL WHERE token=$1", s.token)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to clear sign session", zap.Error(err))
|
||||
}
|
||||
|
||||
_, err = s.server.db.Exec("UPDATE servers SET current_players=$1 WHERE server_id=$2", len(s.server.sessions), s.server.ID)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
_, err = s.server.db.Exec("UPDATE servers SET current_players=$1 WHERE server_id=$2", len(s.server.sessions), s.server.ID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to update player count", zap.Error(err))
|
||||
}
|
||||
}
|
||||
|
||||
if s.stage == nil {
|
||||
|
||||
Reference in New Issue
Block a user