From a8b0dddf17f422c326d609716bee1863d23827b8 Mon Sep 17 00:00:00 2001 From: Ty Sayers Date: Sat, 16 May 2015 13:01:21 -0400 Subject: [PATCH] Add support for redis configuration file to determine viable redis master and slave connections, that can be set to be region-dependant. Fix leakage issue with command manager with not properly returning broken jedis resources. Funnel all redis connection requests through ServerManager for easier configuration use. --- .../src/mineplex/serverdata/Utility.java | 27 +++++- .../commands/ServerCommandManager.java | 18 +++- .../serverdata/redis/RedisConfig.java | 42 +++++++++ .../serverdata/servers/ServerManager.java | 85 ++++++++++++++++--- 4 files changed, 155 insertions(+), 17 deletions(-) create mode 100644 Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java index b848f99cd..688512cfa 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/Utility.java @@ -5,6 +5,7 @@ import mineplex.serverdata.servers.ServerManager; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.exceptions.JedisConnectionException; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -76,9 +77,18 @@ public class Utility { currentTime = Long.parseLong(jedis.time().get(0)); } + catch (JedisConnectionException exception) + { + exception.printStackTrace(); + pool.returnBrokenResource(jedis); + jedis = null; + } finally { - pool.returnResource(jedis); + if (pool != null) + { + pool.returnResource(jedis); + } } return currentTime; @@ -98,9 +108,18 @@ public class Utility { currentTime = Long.parseLong(jedis.time().get(0)); } + catch (JedisConnectionException exception) + { + exception.printStackTrace(); + pool.returnBrokenResource(jedis); + jedis = null; + } finally { - pool.returnResource(jedis); + if (pool != null) + { + pool.returnResource(jedis); + } } return currentTime * 1000; @@ -134,7 +153,9 @@ public class Utility { if (_slavePool == null) { - _slavePool = generatePool(ServerManager.getSlaveConnection()); + ConnectionData slave = ServerManager.getSlaveConnection(); + + _slavePool = generatePool(slave); } return _slavePool; diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/commands/ServerCommandManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/commands/ServerCommandManager.java index d3b88546f..31341ae10 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/commands/ServerCommandManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/commands/ServerCommandManager.java @@ -8,6 +8,7 @@ import mineplex.serverdata.servers.ServerManager; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.exceptions.JedisConnectionException; public class ServerCommandManager { @@ -55,13 +56,17 @@ public class ServerCommandManager { jedis.psubscribe(new ServerCommandListener(), SERVER_COMMANDS_CHANNEL + ":*"); } - catch (Exception exception) + catch (JedisConnectionException exception) { exception.printStackTrace(); + _readPool.returnBrokenResource(jedis); } finally { - _readPool.returnResource(jedis); + if (_readPool != null) + { + _readPool.returnResource(jedis); + } } } }; @@ -87,13 +92,18 @@ public class ServerCommandManager String serializedCommand = Utility.serialize(serverCommand); jedis.publish(SERVER_COMMANDS_CHANNEL + ":" + commandType, serializedCommand); } - catch (Exception exception) + catch (JedisConnectionException exception) { exception.printStackTrace(); + _writePool.returnBrokenResource(jedis); + jedis = null; } finally { - _writePool.returnResource(jedis); + if (_writePool != null) + { + _writePool.returnResource(jedis); + } } } }).start(); diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java new file mode 100644 index 000000000..f2f05001e --- /dev/null +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/redis/RedisConfig.java @@ -0,0 +1,42 @@ +package mineplex.serverdata.redis; + +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import mineplex.serverdata.servers.ConnectionData; + +public class RedisConfig +{ + + private static Random random = new Random(); + + private ConnectionData _masterConnection; + private List _slaveConnections; + + public RedisConfig(ConnectionData master, List slaves) + { + _masterConnection = master; + _slaveConnections = slaves; + } + + public ConnectionData getConnection() + { + return getConnection(true); + } + + public ConnectionData getConnection(boolean writeable) + { + if (writeable) + { + return _masterConnection; + } + else + { + int index = random.nextInt(_slaveConnections.size()); + return _slaveConnections.get(index); + } + } +} diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java index 81a87c6a4..70e01c370 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/servers/ServerManager.java @@ -1,10 +1,15 @@ package mineplex.serverdata.servers; +import java.io.File; +import java.nio.file.Files; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Random; import mineplex.serverdata.Region; +import mineplex.serverdata.redis.RedisConfig; import mineplex.serverdata.redis.RedisServerRepository; /** @@ -14,13 +19,8 @@ import mineplex.serverdata.redis.RedisServerRepository; */ public class ServerManager { - - // Connection host to server database - private static final String DATABASE_HOST = "10.33.53.16"; - - // Ports associated with slave redis instances - private static final int[] SLAVE_PORTS = {6377, 6378, 6380, 6381, 6382}; - private static Random random = new Random(); + // Configuration determining connection information + private static RedisConfig _config = getConfig(); // The cached repository instances private static Map repositories = new HashMap(); @@ -56,7 +56,7 @@ public class ServerManager */ public static ConnectionData getMasterConnection() { - return new ConnectionData(DATABASE_HOST, 6379); + return getConnection(true); } /** @@ -65,7 +65,72 @@ public class ServerManager */ public static ConnectionData getSlaveConnection() { - int port = SLAVE_PORTS[random.nextInt(SLAVE_PORTS.length)]; - return new ConnectionData(DATABASE_HOST, port); + return getConnection(false); + } + + public static ConnectionData getConnection(boolean writeable) + { + System.out.println("fETChing"); + return getConfig().getConnection(writeable); + } + + + public static RedisConfig getConfig() + { + System.out.println("LOADING CONFIG"); + if (_config == null) + { + try + { + System.out.println("STARTING"); + File configFile = new File("redis-config.dat"); + + if (configFile.exists()) + { + List lines = Files.readAllLines(configFile.toPath()); + + ConnectionData master = deserializeConnection(lines.get(0)); + List slaves = new ArrayList(); + + for (int i = 1; i < lines.size(); i++) + { + ConnectionData slave = deserializeConnection(lines.get(i)); + slaves.add(slave); + } + + System.out.println("LOADED " + (master != null) + " " + slaves.size()); + + _config = new RedisConfig(master, slaves); + System.out.println("Master connection " + master.getHost() + " port " + master.getPort()); + } + else + { + System.out.println("DOES NOT EXIST AT PATH " + configFile.toPath().toString()); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + System.out.println("---Unable To Parse Redis Configuration File---"); + } + + } + + return _config; + } + + private static ConnectionData deserializeConnection(String line) + { + String[] args = line.split(" "); + + if (args.length == 2) + { + String ip = args[0]; + int port = Integer.parseInt(args[1]); + + return new ConnectionData(ip, port); + } + + return null; } }