From a2b58798f9a7623000298781236d27ea3a0c6167 Mon Sep 17 00:00:00 2001 From: mohammed jasem alaajel <34905970+ham1255@users.noreply.github.com> Date: Wed, 23 Dec 2020 21:04:23 +0400 Subject: [PATCH] new ConnectionController! --- .../net/limework/rediskript/RediSkript.java | 22 +-- .../commands/CommandReloadRedis.java | 4 +- ...RedisManager.java => RedisController.java} | 163 +++++++----------- .../skript/elements/EffSendMessage.java | 2 +- .../elements/ExprVariableInChannel.java | 4 +- src/main/resources/plugin.yml | 2 +- 6 files changed, 84 insertions(+), 113 deletions(-) rename src/main/java/net/limework/rediskript/managers/{RedisManager.java => RedisController.java} (68%) diff --git a/src/main/java/net/limework/rediskript/RediSkript.java b/src/main/java/net/limework/rediskript/RediSkript.java index c2c1fde..d65e5af 100644 --- a/src/main/java/net/limework/rediskript/RediSkript.java +++ b/src/main/java/net/limework/rediskript/RediSkript.java @@ -8,7 +8,7 @@ import ch.njol.skript.util.Date; import ch.njol.skript.util.Getter; import net.limework.rediskript.commands.CommandReloadRedis; import net.limework.rediskript.events.RedisMessageEvent; -import net.limework.rediskript.managers.RedisManager; +import net.limework.rediskript.managers.RedisController; import net.limework.rediskript.skript.elements.*; import org.bukkit.plugin.java.JavaPlugin; @@ -16,14 +16,14 @@ import java.io.IOException; public class RediSkript extends JavaPlugin { - //Redis manager - private RedisManager rm; + private RedisController redisController; - public void startRedis(boolean reload) { - if (reload) { reloadConfig(); } - rm = new RedisManager(this); - rm.start(); + public void reloadRedis(){ + redisController.shutdown(); + redisController = new RedisController(this); } + + public void registerSyntax() { SkriptAddon addon = Skript.registerAddon(this); try { @@ -60,16 +60,16 @@ public class RediSkript extends JavaPlugin { @Override public void onEnable() { saveDefaultConfig(); - startRedis(false); + redisController = new RedisController(this); getServer().getPluginCommand("reloadredis").setExecutor(new CommandReloadRedis(this)); registerSyntax(); } @Override public void onDisable() { - if (rm != null) rm.shutdown(); + if (redisController != null) redisController.shutdown(); } - public RedisManager getRedisManager() { - return rm; + public RedisController getRC() { + return redisController; } } \ No newline at end of file diff --git a/src/main/java/net/limework/rediskript/commands/CommandReloadRedis.java b/src/main/java/net/limework/rediskript/commands/CommandReloadRedis.java index 4eef890..fc9717b 100644 --- a/src/main/java/net/limework/rediskript/commands/CommandReloadRedis.java +++ b/src/main/java/net/limework/rediskript/commands/CommandReloadRedis.java @@ -27,10 +27,10 @@ public class CommandReloadRedis implements CommandExecutor { new BukkitRunnable() { @Override public void run() { - plugin.getRedisManager().reload(); + plugin.reloadRedis(); } }.runTaskAsynchronously(plugin); - + //not sending to sender, because this command can only be executed via console Bukkit.getLogger().info(ChatColor.translateAlternateColorCodes('&', "&eReloaded channels, encryption and login details!")); diff --git a/src/main/java/net/limework/rediskript/managers/RedisManager.java b/src/main/java/net/limework/rediskript/managers/RedisController.java similarity index 68% rename from src/main/java/net/limework/rediskript/managers/RedisManager.java rename to src/main/java/net/limework/rediskript/managers/RedisController.java index eff0e5c..204227a 100644 --- a/src/main/java/net/limework/rediskript/managers/RedisManager.java +++ b/src/main/java/net/limework/rediskript/managers/RedisController.java @@ -8,46 +8,43 @@ import net.limework.rediskript.events.RedisMessageEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.configuration.Configuration; +import org.bukkit.scheduler.BukkitTask; import org.cryptomator.siv.UnauthenticCiphertextException; import org.json.JSONArray; import org.json.JSONObject; -import redis.clients.jedis.BinaryJedis; -import redis.clients.jedis.BinaryJedisPubSub; -import redis.clients.jedis.JedisPool; -import redis.clients.jedis.JedisPoolConfig; +import redis.clients.jedis.*; import redis.clients.jedis.exceptions.JedisConnectionException; import javax.crypto.IllegalBlockSizeException; import java.nio.charset.StandardCharsets; import java.util.Base64; import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; -public class RedisManager extends BinaryJedisPubSub implements Runnable { - - private ExecutorService RedisReconnector; - private RediSkript plugin; - - private JedisPool jedisPool; - private ExecutorService RedisService; +public class RedisController extends BinaryJedisPubSub implements Runnable { - //sub - private BinaryJedis subscribeJedis; - private List channels; - private AtomicBoolean isShuttingDown = new AtomicBoolean(false); - private Encryption encryption; + //Jedis Pool to be used by every another class. + private final JedisPool jedisPool; + + //this seems useless unless tls is OFF! + private final Encryption encryption; + + private byte[][] channelsInByte; + + private final AtomicBoolean isConnectionBroken; + private final RediSkript plugin; + private BukkitTask ConnectionTask; - public RedisManager(RediSkript plugin) { + public RedisController(RediSkript plugin) { this.plugin = plugin; - Configuration config = this.plugin.getConfig(); + Configuration config = plugin.getConfig(); JedisPoolConfig JConfig = new JedisPoolConfig(); int maxConnections = config.getInt("Redis.MaxConnections"); - if (maxConnections < 2) { maxConnections = 2; } - + if (maxConnections < 2) { + maxConnections = 2; + } JConfig.setMaxTotal(maxConnections); JConfig.setMaxIdle(maxConnections); JConfig.setMinIdle(1); @@ -58,50 +55,34 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { config.getInt("Redis.TimeOut"), config.getString("Redis.Password"), config.getBoolean("Redis.useTLS")); - RedisReconnector = Executors.newSingleThreadExecutor(); - RedisService = Executors.newSingleThreadExecutor(); - try { - this.subscribeJedis = this.jedisPool.getResource(); - } catch (Exception ignored) {} - - this.channels = config.getStringList("Channels"); encryption = new Encryption(config); - - } - - public void start() { - this.RedisReconnector.execute(this); + setupChannels(config); + isConnectionBroken = new AtomicBoolean(true); + //Start the main task on async thread + ConnectionTask = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin,this, 0 , 20 * 5 ); } @Override public void run() { - while (!isShuttingDown.get() && plugin.isEnabled()) { - try { - plugin.getLogger().info(ChatColor.translateAlternateColorCodes('&', "&cConnecting to redis...")); - if (!this.subscribeJedis.isConnected()) this.subscribeJedis = this.jedisPool.getResource(); - plugin.getLogger().info(ChatColor.translateAlternateColorCodes('&', "&aRedis connected!")); - byte[][] channelsInByte = new byte[channels.size()][1]; - for (int x = 0; x < channels.size(); x++) { - channelsInByte[x] = channels.get(x).getBytes(StandardCharsets.UTF_8); - } - this.subscribeJedis.subscribe(this, channelsInByte); - - - } catch (Exception e) { - if (isShuttingDown.get() || !plugin.isEnabled()) { - return; - } - plugin.getLogger().warning(ChatColor.translateAlternateColorCodes('&', "&cConnection to redis has failed! &cReconnecting...")); - if (this.subscribeJedis != null) { - this.subscribeJedis.close(); - } - } - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + if (!isConnectionBroken.get()) { + return; } + System.out.println("connecting to redis!"); + try (Jedis jedis = jedisPool.getResource()) { + isConnectionBroken.set(false); + System.out.println("connected to redis!"); + jedis.subscribe(this, channelsInByte); + + } catch (Exception e) { + isConnectionBroken.set(true); + e.printStackTrace(); + } + } + + public void shutdown() { + ConnectionTask.cancel(); + this.unsubscribe(); + jedisPool.close(); } @Override @@ -170,7 +151,7 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { //I will add this once someone tells me how to remove from Skript variable //because using SET operation has issues with inconvertible types (Double and Long) //variable = (Variable) Variables.getVariable(variableNames.get(i).toString(), null, false); - // variable.change(null, (Object[]) inputValue, Changer.ChangeMode.REMOVE); + // variable.change(null, (Object[]) inputValue, Changer.ChangeMode.REMOVE); break; case "SET": Variables.setVariable(variableNames.get(i).toString(), inputValue, null, false); @@ -186,6 +167,7 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { } } + public void sendMessage(String[] message, String channel) { JSONObject json = new JSONObject(); json.put("Messages", new JSONArray(message)); @@ -193,6 +175,7 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { json.put("Date", System.currentTimeMillis()); //for unique string every time & PING calculations finishSendMessage(json, channel); } + public void sendVariables(String[] variableNames, String[] variableValues, String channel, String operation) { JSONObject json = new JSONObject(); json.put("Names", new JSONArray(variableNames)); @@ -209,8 +192,8 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { public void finishSendMessage(JSONObject json, String channel) { try { byte[] message; - if (this.getEncryption().isEncryptionEnabled()) { - message = this.getEncryption().encrypt(json.toString()); + if (encryption.isEncryptionEnabled()) { + message = encryption.encrypt(json.toString()); } else { message = json.toString().getBytes(StandardCharsets.UTF_8); } @@ -218,51 +201,39 @@ public class RedisManager extends BinaryJedisPubSub implements Runnable { //sending a redis message blocks main thread if there's no more connections available //so to avoid issues, it's best to do it always on separate thread if (plugin.isEnabled()) { - this.getRedisService().execute(() -> { - BinaryJedis j = this.getJedisPool().getResource(); - j.publish(channel.getBytes(StandardCharsets.UTF_8), message); - j.close(); + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> { + try (BinaryJedis j = jedisPool.getResource()) { + j.publish(channel.getBytes(StandardCharsets.UTF_8), message); + } catch (Exception e) { + System.out.println("Error sending redis message!"); + e.printStackTrace(); + } + }); } else { //execute sending of redis message on the main thread if plugin is disabling //so it can still process the sending - BinaryJedis j = this.getJedisPool().getResource(); - j.publish(channel.getBytes(StandardCharsets.UTF_8), message); - j.close(); + try (BinaryJedis j = jedisPool.getResource()) { + j.publish(channel.getBytes(StandardCharsets.UTF_8), message); + } catch (Exception e) { + e.printStackTrace(); + } + } } catch (JedisConnectionException exception) { exception.printStackTrace(); } } - public void shutdown() { - - this.isShuttingDown.set(true); - - if (this.subscribeJedis != null) { - this.unsubscribe(); - this.subscribeJedis.close(); + private void setupChannels(Configuration config) { + List channels = config.getStringList("Channels"); + channelsInByte = new byte[channels.size()][1]; + for (int x = 0; x < channels.size(); x++) { + channelsInByte[x] = channels.get(x).getBytes(StandardCharsets.UTF_8); } - - if (this.jedisPool != null) { - jedisPool.close(); - } - this.RedisReconnector.shutdown(); - this.RedisService.shutdown(); - - } - public void reload() { - this.shutdown(); - plugin.startRedis(true); } - public JedisPool getJedisPool() { - return jedisPool; + public Boolean isRedisConnectionOffline() { + return isConnectionBroken.get(); } - - public Encryption getEncryption() { - return encryption; - } - - public ExecutorService getRedisService() { return RedisService; } } diff --git a/src/main/java/net/limework/rediskript/skript/elements/EffSendMessage.java b/src/main/java/net/limework/rediskript/skript/elements/EffSendMessage.java index f98d5b1..87d1048 100644 --- a/src/main/java/net/limework/rediskript/skript/elements/EffSendMessage.java +++ b/src/main/java/net/limework/rediskript/skript/elements/EffSendMessage.java @@ -35,7 +35,7 @@ public class EffSendMessage extends Effect { Bukkit.getLogger().warning(ChatColor.translateAlternateColorCodes('&', "&2[&aRediSkript&a] &cChannel was empty. Please check your code.")); return; } - plugin.getRedisManager().sendMessage(message, channel); + plugin.getRC().sendMessage(message, channel); } @Override diff --git a/src/main/java/net/limework/rediskript/skript/elements/ExprVariableInChannel.java b/src/main/java/net/limework/rediskript/skript/elements/ExprVariableInChannel.java index 80c760f..757538c 100644 --- a/src/main/java/net/limework/rediskript/skript/elements/ExprVariableInChannel.java +++ b/src/main/java/net/limework/rediskript/skript/elements/ExprVariableInChannel.java @@ -66,10 +66,10 @@ public class ExprVariableInChannel extends SimpleExpression { } } String operation = mode.toString(); - plugin.getRedisManager().sendVariables(name.getAll(e), values, channel.getSingle(e), operation); + plugin.getRC().sendVariables(name.getAll(e), values, channel.getSingle(e), operation); break; case DELETE: - plugin.getRedisManager().sendVariables(name.getAll(e), null, channel.getSingle(e), "SET"); + plugin.getRC().sendVariables(name.getAll(e), null, channel.getSingle(e), "SET"); break; } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3bd822d..01d33a2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,7 +1,7 @@ main: net.limework.rediskript.RediSkript name: ${project.name} version: ${project.version} -authors: [Govindas, ham1255, DaemonicKing] +authors: [Govindas, ham1255, DaemonicKing, limework.net] api-version: 1.13 depend: [Skript] commands: