From e7de226014516d64fd8d04f4bac9d3a1e4145a0b Mon Sep 17 00:00:00 2001 From: radiant-ai Date: Mon, 26 Feb 2024 17:44:25 -0600 Subject: [PATCH] fix lag when collecting counts for offline players and chunks total --- .../mc/collectors/LoadedChunksCollector.java | 57 +++++++++++++++++++ .../mc/{tps => collectors}/TpsCollector.java | 2 +- .../java/de/sldk/mc/metrics/LoadedChunks.java | 18 +++++- .../java/de/sldk/mc/metrics/PlayersTotal.java | 5 ++ src/main/java/de/sldk/mc/metrics/Tps.java | 2 +- .../{tps => collectors}/TpsCollectorTest.java | 2 +- 6 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 src/main/java/de/sldk/mc/collectors/LoadedChunksCollector.java rename src/main/java/de/sldk/mc/{tps => collectors}/TpsCollector.java (98%) rename src/test/java/de/sldk/mc/{tps => collectors}/TpsCollectorTest.java (98%) diff --git a/src/main/java/de/sldk/mc/collectors/LoadedChunksCollector.java b/src/main/java/de/sldk/mc/collectors/LoadedChunksCollector.java new file mode 100644 index 00000000..d2c371b7 --- /dev/null +++ b/src/main/java/de/sldk/mc/collectors/LoadedChunksCollector.java @@ -0,0 +1,57 @@ +package de.sldk.mc.collectors; + +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.event.world.WorldUnloadEvent; + +import java.util.HashMap; +import java.util.Map; + +public class LoadedChunksCollector implements Listener { + + private final Map loadedChunksTotalMap = new HashMap<>(); + + @EventHandler + public void onChunkLoad(ChunkLoadEvent event) { + World world = event.getWorld(); + Integer currentCount = loadedChunksTotalMap.get(world.getName()); + if (currentCount == null) { + loadedChunksTotalMap.put(world.getName(), world.getLoadedChunks().length); + } + else { + loadedChunksTotalMap.put(world.getName(), currentCount + 1); + } + } + + @EventHandler + public void onChunkUnload(ChunkUnloadEvent event) { + World world = event.getWorld(); + Integer currentCount = loadedChunksTotalMap.get(world.getName()); + if (currentCount == null) { + loadedChunksTotalMap.put(world.getName(), world.getLoadedChunks().length); + } + else { + loadedChunksTotalMap.put(world.getName(), currentCount - 1); + } + } + + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + World world = event.getWorld(); + loadedChunksTotalMap.remove(world.getName()); + } + + public int getLoadedChunkTotal(String worldName) { + return loadedChunksTotalMap.computeIfAbsent(worldName, k -> { + World world = Bukkit.getWorld(worldName); + if (world == null) { + return 0; + } + return world.getLoadedChunks().length; + }); + } +} diff --git a/src/main/java/de/sldk/mc/tps/TpsCollector.java b/src/main/java/de/sldk/mc/collectors/TpsCollector.java similarity index 98% rename from src/main/java/de/sldk/mc/tps/TpsCollector.java rename to src/main/java/de/sldk/mc/collectors/TpsCollector.java index 407575e3..431bd369 100644 --- a/src/main/java/de/sldk/mc/tps/TpsCollector.java +++ b/src/main/java/de/sldk/mc/collectors/TpsCollector.java @@ -1,4 +1,4 @@ -package de.sldk.mc.tps; +package de.sldk.mc.collectors; import java.util.LinkedList; import java.util.function.Supplier; diff --git a/src/main/java/de/sldk/mc/metrics/LoadedChunks.java b/src/main/java/de/sldk/mc/metrics/LoadedChunks.java index ee6132b4..688d874e 100644 --- a/src/main/java/de/sldk/mc/metrics/LoadedChunks.java +++ b/src/main/java/de/sldk/mc/metrics/LoadedChunks.java @@ -1,7 +1,9 @@ package de.sldk.mc.metrics; +import de.sldk.mc.collectors.LoadedChunksCollector; import io.prometheus.client.Gauge; import org.bukkit.World; +import org.bukkit.event.HandlerList; import org.bukkit.plugin.Plugin; public class LoadedChunks extends WorldMetric { @@ -12,10 +14,24 @@ public class LoadedChunks extends WorldMetric { .labelNames("world") .create(); + private final LoadedChunksCollector loadedChunksCollector = new LoadedChunksCollector(); + public LoadedChunks(Plugin plugin) { super(plugin, LOADED_CHUNKS); } + @Override + public void enable() { + super.enable(); + getPlugin().getServer().getPluginManager().registerEvents(loadedChunksCollector, getPlugin()); + } + + @Override + public void disable() { + super.disable(); + HandlerList.unregisterAll(loadedChunksCollector); + } + @Override protected void clear() { LOADED_CHUNKS.clear(); @@ -23,6 +39,6 @@ protected void clear() { @Override public void collect(World world) { - LOADED_CHUNKS.labels(world.getName()).set(world.getLoadedChunks().length); + LOADED_CHUNKS.labels(world.getName()).set(loadedChunksCollector.getLoadedChunkTotal(world.getName())); } } diff --git a/src/main/java/de/sldk/mc/metrics/PlayersTotal.java b/src/main/java/de/sldk/mc/metrics/PlayersTotal.java index 1cc5a0be..62041c45 100644 --- a/src/main/java/de/sldk/mc/metrics/PlayersTotal.java +++ b/src/main/java/de/sldk/mc/metrics/PlayersTotal.java @@ -19,4 +19,9 @@ public PlayersTotal(Plugin plugin) { public void doCollect() { PLAYERS.set(Bukkit.getOfflinePlayers().length); } + + @Override + public boolean isAsyncCapable() { + return true; + } } diff --git a/src/main/java/de/sldk/mc/metrics/Tps.java b/src/main/java/de/sldk/mc/metrics/Tps.java index 8ce8562b..652deade 100644 --- a/src/main/java/de/sldk/mc/metrics/Tps.java +++ b/src/main/java/de/sldk/mc/metrics/Tps.java @@ -1,6 +1,6 @@ package de.sldk.mc.metrics; -import de.sldk.mc.tps.TpsCollector; +import de.sldk.mc.collectors.TpsCollector; import io.prometheus.client.Gauge; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; diff --git a/src/test/java/de/sldk/mc/tps/TpsCollectorTest.java b/src/test/java/de/sldk/mc/collectors/TpsCollectorTest.java similarity index 98% rename from src/test/java/de/sldk/mc/tps/TpsCollectorTest.java rename to src/test/java/de/sldk/mc/collectors/TpsCollectorTest.java index 11d87140..28105dc4 100644 --- a/src/test/java/de/sldk/mc/tps/TpsCollectorTest.java +++ b/src/test/java/de/sldk/mc/collectors/TpsCollectorTest.java @@ -1,4 +1,4 @@ -package de.sldk.mc.tps; +package de.sldk.mc.collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when;