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).

This commit is contained in:
LevelX2 2014-04-25 14:57:45 +02:00
parent ec692902c7
commit 628cf2e018
3 changed files with 44 additions and 51 deletions

View file

@ -321,25 +321,19 @@ public class User {
} }
public void kill(DisconnectReason reason) { public void kill(DisconnectReason reason) {
logger.debug("kill: game sessions " + gameSessions.size());
for (GameSession gameSession: gameSessions.values()) { for (GameSession gameSession: gameSessions.values()) {
gameSession.kill(); gameSession.kill();
} }
logger.debug("kill: draft sessions " + draftSessions.size());
for (DraftSession draftSession: draftSessions.values()) { for (DraftSession draftSession: draftSessions.values()) {
draftSession.setKilled(); draftSession.setKilled();
} }
logger.debug("kill: tournament sessions " + tournamentSessions.size());
for (TournamentSession tournamentSession: tournamentSessions.values()) { for (TournamentSession tournamentSession: tournamentSessions.values()) {
tournamentSession.setKilled(); tournamentSession.setKilled();
} }
logger.debug("kill: tables " + tables.size());
for (Entry<UUID, Table> entry: tables.entrySet()) { for (Entry<UUID, Table> entry: tables.entrySet()) {
TableManager.getInstance().leaveTable(userId, entry.getValue().getId()); TableManager.getInstance().leaveTable(userId, entry.getValue().getId());
} }
logger.debug("kill: remove user from chat before");
ChatManager.getInstance().removeUser(userId, reason); ChatManager.getInstance().removeUser(userId, reason);
logger.debug("kill: remove user from chat after");
} }
public void setUserData(UserData userData) { public void setUserData(UserData userData) {

View file

@ -33,9 +33,11 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import mage.server.util.ThreadExecutor;
import mage.view.ChatMessage.MessageColor; import mage.view.ChatMessage.MessageColor;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -57,23 +59,13 @@ public class UserManager {
return INSTANCE; return INSTANCE;
} }
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
private UserManager() { private UserManager() {
Thread.setDefaultUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage());
e.printStackTrace();
}
});
expireExecutor.scheduleAtFixedRate(new Runnable() { expireExecutor.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
logger.debug("Check expired start");
checkExpired(); checkExpired();
logger.debug("Check expired end");
} }
}, 60, 60, TimeUnit.SECONDS); }, 60, 60, TimeUnit.SECONDS);
} }
@ -119,8 +111,6 @@ public class UserManager {
if (users.containsKey(userId)) { if (users.containsKey(userId)) {
User user = users.get(userId); User user = users.get(userId);
user.setSessionId(""); // Session will be set again with new id if user reconnects 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); 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() { private void checkExpired() {
// 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(); Calendar expired = Calendar.getInstance();
expired.add(Calendar.MINUTE, -3) ; expired.add(Calendar.MINUTE, -3);
List<User> usersToCheck = new ArrayList<>(); List<User> usersToCheck = new ArrayList<>();
usersToCheck.addAll(users.values()); usersToCheck.addAll(users.values());
for (User user: usersToCheck) { for (User user : usersToCheck) {
if (user.isExpired(expired.getTime())) { if (user.isExpired(expired.getTime())) {
logger.info(new StringBuilder(user.getName()).append(" session expired userId: ").append(user.getId()) logger.info(new StringBuilder(user.getName()).append(": session expired userId: ").append(user.getId())
.append(" sessionId: ").append(user.getSessionId())); .append(" Host: ").append(user.getHost()));
user.kill(User.DisconnectReason.LostConnection); user.kill(User.DisconnectReason.LostConnection);
logger.debug("check Expired: Removing user");
users.remove(user.getId()); users.remove(user.getId());
logger.debug("check Expired: user removed");
} }
} }
} }
}
);
} catch (Exception ex) {
handleException(ex);
}
}
public void handleException(Exception ex) {
if (!ex.getMessage().equals("No message")) {
logger.fatal("", ex);
}
}
} }

View file

@ -28,20 +28,17 @@
package mage.server.game; package mage.server.game;
import java.util.UUID;
import mage.game.Game; import mage.game.Game;
import mage.game.match.Match;
import mage.interfaces.callback.ClientCallback; import mage.interfaces.callback.ClientCallback;
import mage.server.User; import mage.server.User;
import mage.server.UserManager; import mage.server.UserManager;
import mage.view.GameClientMessage; import mage.view.GameClientMessage;
import mage.view.GameEndView;
import mage.view.GameView; import mage.view.GameView;
import org.apache.log4j.Logger; 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 * @author BetaSteward_at_googlemail.com
@ -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() { public void setKilled() {
killed = true; killed = true;
} }