GUAC-574: Synchronize across ActiveConnectionMap to prevent connection usage race conditions. Need to revisit architecture of connection management within MySQL.

This commit is contained in:
Michael Jumper
2014-03-26 16:47:27 -07:00
parent 633535c83e
commit b6ccf4c2f3
3 changed files with 77 additions and 66 deletions

View File

@@ -39,7 +39,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket {
* Injected ActiveConnectionMap which will contain all active connections.
*/
@Inject
private ActiveConnectionMap activeConnectionSet;
private ActiveConnectionMap activeConnectionMap;
/**
* The wrapped socket.
@@ -67,7 +67,7 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket {
* @param connectionGroupID The ID of the balancing connection group that is
* being connected to; null if not used.
*/
public void init(GuacamoleSocket socket, int connectionID, int userID,
public void init(GuacamoleSocket socket,
int historyID, Integer connectionGroupID) {
this.socket = socket;
this.historyID = historyID;
@@ -91,7 +91,10 @@ public class MySQLGuacamoleSocket implements GuacamoleSocket {
socket.close();
// Mark this connection as inactive
activeConnectionSet.closeConnection(historyID, connectionGroupID);
synchronized (activeConnectionMap) {
activeConnectionMap.closeConnection(historyID, connectionGroupID);
}
}
@Override

View File

@@ -176,7 +176,7 @@ public class ConnectionGroupService {
* Connect to the connection within the given group with the lowest number
* of currently active users.
*
* @param connection The group to load balance across.
* @param group The group to load balance across.
* @param info The information to use when performing the connection
* handshake.
* @param userID The ID of the user who is connecting to the socket.
@@ -191,6 +191,8 @@ public class ConnectionGroupService {
List<Integer> connectionIDs = connectionService.getAllConnectionIDs
(group.getConnectionGroupID());
synchronized (activeConnectionMap) {
// Get the least used connection.
Integer leastUsedConnectionID =
activeConnectionMap.getLeastUsedConnection(connectionIDs);
@@ -216,6 +218,9 @@ public class ConnectionGroupService {
// Connect to the connection
return connectionService.connect(connection, info, userID, group.getConnectionGroupID());
}
}
/**

View File

@@ -322,6 +322,8 @@ public class ConnectionService {
GuacamoleClientInformation info, int userID, Integer connectionGroupID)
throws GuacamoleException {
synchronized (activeConnectionMap) {
// If the given connection is active, and multiple simultaneous
// connections are not allowed, disallow connection
if(GuacamoleProperties.getProperty(
@@ -358,13 +360,14 @@ public class ConnectionService {
// Return new MySQLGuacamoleSocket
MySQLGuacamoleSocket mySQLGuacamoleSocket = mySQLGuacamoleSocketProvider.get();
mySQLGuacamoleSocket.init(socket, connection.getConnectionID(), userID,
historyID, connectionGroupID);
mySQLGuacamoleSocket.init(socket, historyID, connectionGroupID);
return mySQLGuacamoleSocket;
}
}
/**
* Creates a new connection having the given name and protocol.
*