diff --git a/src/main/java/com/io/yutian/aulib/AuLib.java b/src/main/java/com/io/yutian/aulib/AuLib.java index e9709a8..c726b80 100644 --- a/src/main/java/com/io/yutian/aulib/AuLib.java +++ b/src/main/java/com/io/yutian/aulib/AuLib.java @@ -2,6 +2,7 @@ package com.io.yutian.aulib; import com.io.yutian.aulib.lang.Lang; import com.io.yutian.aulib.listener.GuiHandlerListener; +import com.io.yutian.aulib.redis.RedisCacheSyncTimer; import com.io.yutian.aulib.util.LangUtil; import org.bukkit.plugin.java.JavaPlugin; @@ -9,10 +10,14 @@ public class AuLib extends JavaPlugin { private static AuLib instance; + private RedisCacheSyncTimer redisCacheSyncTimer; + @Override public void onEnable() { instance = this; + redisCacheSyncTimer = new RedisCacheSyncTimer(); + registerListeners(); Lang.registerLangFile(this); @@ -22,11 +27,14 @@ public class AuLib extends JavaPlugin { } - private void registerListeners() { new GuiHandlerListener(this); } + public RedisCacheSyncTimer getRedisCacheSyncTimer() { + return redisCacheSyncTimer; + } + public static AuLib inst() { return instance; } diff --git a/src/main/java/com/io/yutian/aulib/redis/IJedisGetter.java b/src/main/java/com/io/yutian/aulib/redis/IJedisGetter.java new file mode 100644 index 0000000..65e3aa6 --- /dev/null +++ b/src/main/java/com/io/yutian/aulib/redis/IJedisGetter.java @@ -0,0 +1,9 @@ +package com.io.yutian.aulib.redis; + +import redis.clients.jedis.Jedis; + +public interface IJedisGetter { + + Jedis getRedis(); + +} diff --git a/src/main/java/com/io/yutian/aulib/redis/RedisCacheHelper.java b/src/main/java/com/io/yutian/aulib/redis/RedisCacheHelper.java deleted file mode 100644 index 6875ad5..0000000 --- a/src/main/java/com/io/yutian/aulib/redis/RedisCacheHelper.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.io.yutian.aulib.redis; - -public class RedisCacheHelper { - - public static void updateCache(String key, String value) { - - } - -} diff --git a/src/main/java/com/io/yutian/aulib/redis/RedisCacheSyncTimer.java b/src/main/java/com/io/yutian/aulib/redis/RedisCacheSyncTimer.java new file mode 100644 index 0000000..1acd169 --- /dev/null +++ b/src/main/java/com/io/yutian/aulib/redis/RedisCacheSyncTimer.java @@ -0,0 +1,106 @@ +package com.io.yutian.aulib.redis; + +import com.io.yutian.aulib.AuLib; +import it.unimi.dsi.fastutil.Pair; +import org.bukkit.plugin.Plugin; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import redis.clients.jedis.Jedis; + +import java.util.HashMap; +import java.util.Map; + +public class RedisCacheSyncTimer { + + private static final String LOCK_KEY = "sync_lock"; + private static final int LOCK_EXPIRE_SECONDS = 600; + private final Map pluginInfos = new HashMap<>(); + + private BukkitTask task; + + public RedisCacheSyncTimer() { + task = new BukkitRunnable() { + @Override + public void run() { + if (pluginInfos.isEmpty()) { + return; + } + for (Map.Entry entry : pluginInfos.entrySet()) { + Plugin plugin = entry.getKey(); + if (!plugin.isEnabled()) { + continue; + } + PluginInfo pluginInfo = entry.getValue(); + String lockKey = LOCK_KEY + "_" + plugin.getName(); + IJedisGetter jedisGetter = pluginInfo.getJedisGetter(); + try (Jedis jedis = jedisGetter.getRedis()) { + long lockResult = jedis.setnx(lockKey, "locked"); + if (lockResult != 1) { + break; + } + jedis.expire(lockKey, LOCK_EXPIRE_SECONDS); + for (Map.Entry, RedisCacheSynchronizer> entry1 : entry.getValue().getSynchronizers().entrySet()) { + Pair key = entry1.getKey(); + RedisCacheSynchronizer synchronizer = entry1.getValue(); + String k1 = key.first(); + String k2 = key.second(); + String data = null; + if (k2 == null) { + data = jedis.get(k1); + } else { + data = jedis.hget(k1, k2); + } + if (data != null) { + String finalData = data; + synchronizer.sync(finalData); + if (k2 == null) { + jedis.del(k1); + } else { + jedis.hdel(k1, k2); + } + } + } + } + } + } + }.runTaskTimerAsynchronously(AuLib.inst(), 0L, 10L * 20 * 60L); + } + + public void registerSynchronizer(Plugin plugin, IJedisGetter jedisGetter, Pair key, RedisCacheSynchronizer synchronizer) { + PluginInfo pluginInfo = pluginInfos.computeIfAbsent(plugin, k -> new PluginInfo(jedisGetter)); + pluginInfo.addSynchronizer(key, synchronizer); + pluginInfos.put(plugin, pluginInfo); + } + + class PluginInfo { + + private IJedisGetter jedisGetter; + private Map, RedisCacheSynchronizer> synchronizers; + + public PluginInfo(IJedisGetter jedisGetter) { + this.jedisGetter = jedisGetter; + this.synchronizers = new HashMap<>(); + } + + public void addSynchronizer(Pair key, RedisCacheSynchronizer synchronizer) { + if (key == null || synchronizer == null) { + return; + } + if (synchronizers.containsKey(key)) { + throw new IllegalArgumentException("Key already registered: " + key); + } + synchronizers.put(key, synchronizer); + } + + public IJedisGetter getJedisGetter() { + return jedisGetter; + } + + public Map, RedisCacheSynchronizer> getSynchronizers() { + return synchronizers; + } + + } + +} + diff --git a/src/main/java/com/io/yutian/aulib/redis/RedisCacheSynchronizer.java b/src/main/java/com/io/yutian/aulib/redis/RedisCacheSynchronizer.java new file mode 100644 index 0000000..6c0c6d7 --- /dev/null +++ b/src/main/java/com/io/yutian/aulib/redis/RedisCacheSynchronizer.java @@ -0,0 +1,8 @@ +package com.io.yutian.aulib.redis; + +@FunctionalInterface +public interface RedisCacheSynchronizer { + + void sync(String data); + +} diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fbff55e..9025286 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: AuLib main: com.io.yutian.aulib.AuLib -version: 2.1 +version: 2.2 api-version: 1.18 author: SuperYuTian \ No newline at end of file