mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
* Session locking - Fixed some problems with the reentrant lock.
This commit is contained in:
parent
2af52cfd3a
commit
896793b93d
4 changed files with 92 additions and 47 deletions
|
@ -63,6 +63,7 @@ import java.net.InetAddress;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import static mage.server.Session.getBasicCause;
|
||||||
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;
|
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;
|
||||||
|
|
||||||
|
|
||||||
|
@ -213,18 +214,16 @@ public class Main {
|
||||||
//SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.Disconnected);
|
//SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.Disconnected);
|
||||||
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
|
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
|
||||||
logger.info("CLIENT DISCONNECTED - " + sessionInfo, throwable);
|
logger.info("CLIENT DISCONNECTED - " + sessionInfo, throwable);
|
||||||
if (logger.isDebugEnabled()) {
|
logger.debug("Stack Trace", throwable);
|
||||||
throwable.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
|
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
|
||||||
logger.info("CONNECTION LOST - " + sessionInfo, throwable);
|
logger.info("LOST CONNECTION - " + sessionInfo);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
logger.debug("Lease expired");
|
logger.debug("- cause: Lease expired");
|
||||||
} else {
|
} else {
|
||||||
throwable.printStackTrace();
|
logger.debug(" - cause: " + Session.getBasicCause(throwable).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -213,8 +212,10 @@ public class Session {
|
||||||
|
|
||||||
// because different threads can activate this
|
// because different threads can activate this
|
||||||
public void userLostConnection() {
|
public void userLostConnection() {
|
||||||
|
boolean lockSet = false;
|
||||||
try {
|
try {
|
||||||
if(lock.tryLock(5, TimeUnit.SECONDS)) {
|
if(lock.tryLock(500, TimeUnit.MILLISECONDS)) {
|
||||||
|
lockSet = true;
|
||||||
User user = UserManager.getInstance().getUser(userId);
|
User user = UserManager.getInstance().getUser(userId);
|
||||||
if (user == null || !user.isConnected()) {
|
if (user == null || !user.isConnected()) {
|
||||||
return; //user was already disconnected by other thread
|
return; //user was already disconnected by other thread
|
||||||
|
@ -224,46 +225,70 @@ public class Session {
|
||||||
logger.info("OLD SESSION IGNORED - " + user.getName());
|
logger.info("OLD SESSION IGNORED - " + user.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.info("LOST CONNECTION - " + user.getName());
|
logger.info("LOST CONNECTION - " + user.getName() + " id: " + userId);
|
||||||
UserManager.getInstance().disconnect(userId, DisconnectReason.LostConnection);
|
UserManager.getInstance().disconnect(userId, DisconnectReason.LostConnection);
|
||||||
} else {
|
} else {
|
||||||
logger.error("SESSION LOCK - userId " + userId);
|
logger.error("SESSION LOCK lost connection - userId: " + userId);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
logger.error("SESSION LOCK - userId " + userId, ex);
|
logger.error("SESSION LOCK lost connection - userId: " + userId, ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.unlock();
|
if (lockSet) {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void kill(DisconnectReason reason) {
|
public void kill(DisconnectReason reason) {
|
||||||
UserManager.getInstance().removeUser(userId, reason);
|
boolean lockSet = false;
|
||||||
|
try {
|
||||||
|
if(lock.tryLock(500, TimeUnit.MILLISECONDS)) {
|
||||||
|
lockSet = true;
|
||||||
|
UserManager.getInstance().removeUser(userId, reason);
|
||||||
|
} else {
|
||||||
|
logger.error("SESSION LOCK - kill: userId " + userId);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
logger.error("SESSION LOCK - kill: userId " + userId, ex);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (lockSet) {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireCallback(final ClientCallback call) {
|
public void fireCallback(final ClientCallback call) {
|
||||||
|
boolean lockSet = false;
|
||||||
try {
|
try {
|
||||||
boolean tryLock;
|
if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
|
||||||
if (lock.tryLock(5, TimeUnit.SECONDS)) {
|
lockSet = true;
|
||||||
call.setMessageId(messageId++);
|
call.setMessageId(messageId++);
|
||||||
callbackHandler.handleCallbackOneway(new Callback(call));
|
callbackHandler.handleCallbackOneway(new Callback(call));
|
||||||
} else {
|
} else {
|
||||||
logger.error("CALLBACK LOCK - userId " + userId);
|
logger.error("SESSION LOCK callback: userId " + userId);
|
||||||
logger.error(" - method: " + call.getMethod());
|
logger.error(" - method: " + call.getMethod());
|
||||||
}
|
}
|
||||||
} catch (HandleCallbackException ex) {
|
} catch (HandleCallbackException ex) {
|
||||||
logger.info("CALLBACK EXCEPTION - userId " + userId, ex);
|
User user = UserManager.getInstance().getUser(userId);
|
||||||
if (logger.isDebugEnabled()) {
|
logger.warn("SESSION CALLBACK EXCEPTION - " + (user != null ? user.getName():"") + " userId " + userId);
|
||||||
ex.printStackTrace();
|
logger.warn(" - method: " + call.getMethod());
|
||||||
}
|
logger.warn(" - cause: " + getBasicCause(ex).toString());
|
||||||
|
logger.trace("Stack trace:", ex);
|
||||||
userLostConnection();
|
userLostConnection();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
logger.error("CALLBACK LOCK EXCEPTION - userId " + userId, ex);
|
logger.error("SESSION LOCK callback -userId: " + userId);
|
||||||
logger.error(" - method: " + call.getMethod());
|
logger.error(" - method: " + call.getMethod());
|
||||||
|
logger.error(" - cause: " + getBasicCause(ex).toString());
|
||||||
|
logger.trace("Stack trace:", ex);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
lock.unlock();
|
if (lockSet) {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,4 +318,15 @@ public class Session {
|
||||||
messageData.add(message);
|
messageData.add(message);
|
||||||
fireCallback(new ClientCallback("showUserMessage", null, messageData));
|
fireCallback(new ClientCallback("showUserMessage", null, messageData));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Throwable getBasicCause(Throwable cause) {
|
||||||
|
Throwable t = cause;
|
||||||
|
while (t.getCause() != null) {
|
||||||
|
t = t.getCause();
|
||||||
|
if (t == cause) {
|
||||||
|
throw new IllegalArgumentException("Infinite cycle detected in causal chain");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,28 +115,26 @@ public class SessionManager {
|
||||||
Session session = sessions.get(sessionId);
|
Session session = sessions.get(sessionId);
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
if (!reason.equals(DisconnectReason.AdminDisconnect)) {
|
if (!reason.equals(DisconnectReason.AdminDisconnect)) {
|
||||||
synchronized (session) {
|
if (!sessions.containsKey(sessionId)) {
|
||||||
if (!sessions.containsKey(sessionId)) {
|
// session was removed meanwhile by another thread so we can return
|
||||||
// session was removed meanwhile by another thread so we can return
|
return;
|
||||||
return;
|
}
|
||||||
}
|
sessions.remove(sessionId);
|
||||||
sessions.remove(sessionId);
|
switch (reason) {
|
||||||
switch (reason) {
|
case Disconnected:
|
||||||
case Disconnected:
|
session.kill(reason);
|
||||||
session.kill(reason);
|
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_KILLED, sessionId);
|
||||||
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_KILLED, sessionId);
|
break;
|
||||||
break;
|
case SessionExpired:
|
||||||
case SessionExpired:
|
session.kill(reason);
|
||||||
session.kill(reason);
|
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_EXPIRED, sessionId);
|
||||||
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_EXPIRED, sessionId);
|
break;
|
||||||
break;
|
case LostConnection:
|
||||||
case LostConnection:
|
session.userLostConnection();
|
||||||
session.userLostConnection();
|
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId);
|
||||||
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId);
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: "+ sessionId);
|
||||||
logger.error("endSession: unexpected reason " + reason.toString() + " - sessionId: "+ sessionId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sessions.remove(sessionId);
|
sessions.remove(sessionId);
|
||||||
|
|
|
@ -29,6 +29,7 @@ package mage.server;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -123,14 +124,25 @@ public class User {
|
||||||
this.sessionId = sessionId;
|
this.sessionId = sessionId;
|
||||||
if (sessionId.isEmpty()) {
|
if (sessionId.isEmpty()) {
|
||||||
userState = UserState.Disconnected;
|
userState = UserState.Disconnected;
|
||||||
logger.debug("Disconnected User " + userName + " id: " + userId);
|
lostConnection();
|
||||||
|
logger.debug("USER - lost connection: " + userName + " id: " + userId);
|
||||||
|
|
||||||
} else if (userState == UserState.Created) {
|
} else if (userState == UserState.Created) {
|
||||||
userState = UserState.Connected;
|
userState = UserState.Connected;
|
||||||
logger.debug("Created user " + userName + " id: " + userId);
|
logger.debug("USER - created: " + userName + " id: " + userId);
|
||||||
} else {
|
} else {
|
||||||
userState = UserState.Reconnected;
|
userState = UserState.Reconnected;
|
||||||
reconnect();
|
reconnect();
|
||||||
logger.info("Reconnected user " + userName + " id: " + userId);
|
logger.info("USER - reconnected: " + userName + " id: " + userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lostConnection() {
|
||||||
|
// Because watched games don't get restored after reconnection call stop watching
|
||||||
|
for (Iterator<UUID> iterator = watchedGames.iterator(); iterator.hasNext();) {
|
||||||
|
UUID gameId = iterator.next();
|
||||||
|
GameManager.getInstance().stopWatching(gameId, userId);
|
||||||
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue