From 628cf2e0183d4d04ad5ed214b7a94c47d2af7f4c Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Fri, 25 Apr 2014 14:57:45 +0200 Subject: [PATCH] Fixed that user expired sceduled job died without reporting causing error. Handling changed so that if an exception raises it does not prevent the server to check expired user next time. (Hope this will workaround the existing nasty problem in user handling and show the error causing code sequence). --- .../src/main/java/mage/server/User.java | 6 -- .../main/java/mage/server/UserManager.java | 65 ++++++++++--------- .../java/mage/server/game/GameWatcher.java | 24 +++---- 3 files changed, 44 insertions(+), 51 deletions(-) diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java index d626769b659..00808c6276d 100644 --- a/Mage.Server/src/main/java/mage/server/User.java +++ b/Mage.Server/src/main/java/mage/server/User.java @@ -321,25 +321,19 @@ public class User { } public void kill(DisconnectReason reason) { - logger.debug("kill: game sessions " + gameSessions.size()); for (GameSession gameSession: gameSessions.values()) { gameSession.kill(); } - logger.debug("kill: draft sessions " + draftSessions.size()); for (DraftSession draftSession: draftSessions.values()) { draftSession.setKilled(); } - logger.debug("kill: tournament sessions " + tournamentSessions.size()); for (TournamentSession tournamentSession: tournamentSessions.values()) { tournamentSession.setKilled(); } - logger.debug("kill: tables " + tables.size()); for (Entry entry: tables.entrySet()) { TableManager.getInstance().leaveTable(userId, entry.getValue().getId()); } - logger.debug("kill: remove user from chat before"); ChatManager.getInstance().removeUser(userId, reason); - logger.debug("kill: remove user from chat after"); } public void setUserData(UserData userData) { diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManager.java index b16d98bb20c..58f9fa275a5 100644 --- a/Mage.Server/src/main/java/mage/server/UserManager.java +++ b/Mage.Server/src/main/java/mage/server/UserManager.java @@ -33,9 +33,11 @@ import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import mage.server.util.ThreadExecutor; import mage.view.ChatMessage.MessageColor; import org.apache.log4j.Logger; @@ -57,23 +59,13 @@ public class UserManager { return INSTANCE; } - private UserManager() { - - Thread.setDefaultUncaughtExceptionHandler( - new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(Thread t, Throwable e) { - System.out.println(t.getName() + ": " + e.getMessage()); - e.printStackTrace(); - } - }); - + private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); + + private UserManager() { expireExecutor.scheduleAtFixedRate(new Runnable() { @Override public void run() { - logger.debug("Check expired start"); checkExpired(); - logger.debug("Check expired end"); } }, 60, 60, TimeUnit.SECONDS); } @@ -119,8 +111,6 @@ public class UserManager { if (users.containsKey(userId)) { User user = users.get(userId); user.setSessionId(""); // Session will be set again with new id if user reconnects - // ChatManager.getInstance().broadcast(userId, "has lost connection", MessageColor.BLACK); - logger.info(new StringBuilder("User ").append(user.getName()).append(" has lost connection userId:").append(userId)); } ChatManager.getInstance().removeUser(userId, reason); } @@ -158,23 +148,40 @@ public class UserManager { } /** - * Is the connection lost for more than 3 minutes, the user will be removed (within 3 minutes he can reconnect) + * Is the connection lost for more than 3 minutes, the user will be removed (within 3 minutes the user can reconnect) */ private void checkExpired() { - Calendar expired = Calendar.getInstance(); - expired.add(Calendar.MINUTE, -3) ; - List usersToCheck = new ArrayList<>(); - usersToCheck.addAll(users.values()); - for (User user: usersToCheck) { - if (user.isExpired(expired.getTime())) { - logger.info(new StringBuilder(user.getName()).append(" session expired userId: ").append(user.getId()) - .append(" sessionId: ").append(user.getSessionId())); - user.kill(User.DisconnectReason.LostConnection); - logger.debug("check Expired: Removing user"); - users.remove(user.getId()); - logger.debug("check Expired: user removed"); - } + // calling this with executer saves the sceduled job to be dying becuase of exception. + // Also exceptions were not reported as now with this handling + try { + callExecutor.execute( + new Runnable() { + @Override + public void run() { + Calendar expired = Calendar.getInstance(); + expired.add(Calendar.MINUTE, -3); + List usersToCheck = new ArrayList<>(); + usersToCheck.addAll(users.values()); + for (User user : usersToCheck) { + if (user.isExpired(expired.getTime())) { + logger.info(new StringBuilder(user.getName()).append(": session expired userId: ").append(user.getId()) + .append(" Host: ").append(user.getHost())); + user.kill(User.DisconnectReason.LostConnection); + users.remove(user.getId()); + } + } + } + } + ); + + } catch (Exception ex) { + handleException(ex); } } + public void handleException(Exception ex) { + if (!ex.getMessage().equals("No message")) { + logger.fatal("", ex); + } + } } diff --git a/Mage.Server/src/main/java/mage/server/game/GameWatcher.java b/Mage.Server/src/main/java/mage/server/game/GameWatcher.java index ff492d09812..e2368005c6f 100644 --- a/Mage.Server/src/main/java/mage/server/game/GameWatcher.java +++ b/Mage.Server/src/main/java/mage/server/game/GameWatcher.java @@ -28,20 +28,17 @@ package mage.server.game; +import java.util.UUID; import mage.game.Game; +import mage.game.match.Match; import mage.interfaces.callback.ClientCallback; import mage.server.User; import mage.server.UserManager; import mage.view.GameClientMessage; +import mage.view.GameEndView; import mage.view.GameView; import org.apache.log4j.Logger; -import java.rmi.RemoteException; -import java.util.UUID; -import mage.game.GameState; -import mage.game.match.Match; -import mage.view.GameEndView; - /** * * @author BetaSteward_at_googlemail.com @@ -74,10 +71,10 @@ public class GameWatcher { public void update() { if (!killed) { - User user = UserManager.getInstance().getUser(userId); - if (user != null) { - user.fireCallback(new ClientCallback("gameUpdate", game.getId(), getGameView())); - } + User user = UserManager.getInstance().getUser(userId); + if (user != null) { + user.fireCallback(new ClientCallback("gameUpdate", game.getId(), getGameView())); + } } } @@ -117,11 +114,6 @@ public class GameWatcher { } } - protected void handleRemoteException(RemoteException ex) { - logger.fatal("GameWatcher error", ex); - GameManager.getInstance().kill(game.getId(), userId); - } - public void setKilled() { killed = true; } @@ -137,5 +129,5 @@ public class GameWatcher { public boolean isPlayer() { return isPlayer; } - + }