From 855baff877dfcb8ce9c74bc81245962ca8b790d6 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Thu, 24 Jan 2019 21:42:47 +0400 Subject: [PATCH] Fixed rare infinite loops on user session disconnects; --- .../main/java/mage/server/SessionManager.java | 62 +++++++++++-------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManager.java index a0a30d2edd0..20d201e6c30 100644 --- a/Mage.Server/src/main/java/mage/server/SessionManager.java +++ b/Mage.Server/src/main/java/mage/server/SessionManager.java @@ -30,7 +30,7 @@ public enum SessionManager { if (session.getUserId() != null && !UserManager.instance.getUser(session.getUserId()).isPresent()) { logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed."); // can happen if user from same host signs in multiple time with multiple clients, after he disconnects with one client - disconnect(sessionId, DisconnectReason.ConnectingOtherInstance); + disconnect(sessionId, DisconnectReason.ConnectingOtherInstance, session); // direct disconnect return Optional.empty(); } return Optional.of(session); @@ -96,32 +96,42 @@ public enum SessionManager { } public void disconnect(String sessionId, DisconnectReason reason) { - getSession(sessionId).ifPresent(session -> { - if (!isValidSession(sessionId)) { - // session was removed meanwhile by another thread so we can return - return; - } - logger.debug("DISCONNECT " + reason.toString() + " - sessionId: " + sessionId); - sessions.remove(sessionId); - switch (reason) { - case AdminDisconnect: - session.kill(reason); - break; - case ConnectingOtherInstance: - case Disconnected: // regular session end or wrong client version - UserManager.instance.disconnect(session.getUserId(), reason); - break; - case SessionExpired: // session ends after no reconnect happens in the defined time span - break; - case LostConnection: // user lost connection - session expires countdown starts - session.userLostConnection(); - UserManager.instance.disconnect(session.getUserId(), reason); - break; - default: - logger.trace("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId); - } - }); + disconnect(sessionId, reason, null); + } + public void disconnect(String sessionId, DisconnectReason reason, Session directSession) { + if (directSession == null) { + // find real session to disconnects + getSession(sessionId).ifPresent(session -> { + if (!isValidSession(sessionId)) { + // session was removed meanwhile by another thread so we can return + return; + } + logger.debug("DISCONNECT " + reason.toString() + " - sessionId: " + sessionId); + sessions.remove(sessionId); + switch (reason) { + case AdminDisconnect: + session.kill(reason); + break; + case ConnectingOtherInstance: + case Disconnected: // regular session end or wrong client version + UserManager.instance.disconnect(session.getUserId(), reason); + break; + case SessionExpired: // session ends after no reconnect happens in the defined time span + break; + case LostConnection: // user lost connection - session expires countdown starts + session.userLostConnection(); + UserManager.instance.disconnect(session.getUserId(), reason); + break; + default: + logger.trace("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId); + } + }); + } else { + // direct session to disconnects + sessions.remove(sessionId); + directSession.kill(reason); + } }