From 5b0465efeb9c5fb6d47d073b9e8bac938707175d Mon Sep 17 00:00:00 2001 From: MrHua269 Date: Sun, 10 Mar 2024 05:09:51 +0000 Subject: [PATCH] Added a simple watchdog for tick regions --- ...d-a-simple-watchdog-for-tick-regions.patch | 257 ++++++++++++++++++ ... 0016-Io_uring-channel-type-support.patch} | 0 ...-fixing-folia-spector-teleportation.patch} | 0 ...-entity-was-moving-to-another-regio.patch} | 0 ...sync-calling-during-moving-event-be.patch} | 0 ...020-Piston-fixes-from-molean-server.patch} | 0 ...u-linear-region-format-and-settings.patch} | 2 +- ...aiiju-Don-t-pathfind-outside-region.patch} | 0 ...ju-Vanilla-end-portal-teleportation.patch} | 0 ...> 0024-Kaiiju-Async-path-processing.patch} | 0 ...ch => 0025-Petal-Reduce-sensor-work.patch} | 0 ...fish-Optimize-entity-coordinate-key.patch} | 0 ...Cache-climbing-check-for-activation.patch} | 2 +- ...ish-Improve-fluid-direction-caching.patch} | 0 ...029-Pufferfish-Optimize-suffocation.patch} | 2 +- ...return-optimization-for-target-find.patch} | 0 ...erfish-Reduce-chunk-loading-lookups.patch} | 0 ...ve-container-checking-with-a-bitset.patch} | 2 +- ...per-6045-block-goal-shouldn-t-load-.patch} | 0 ...e-entity-fluid-lookups-if-no-fluids.patch} | 0 ...heck-for-spooky-season-once-an-hour.patch} | 0 ...patch => 0036-Pufferfish-Entity-TTL.patch} | 0 ...ish-Reduce-projectile-chunk-loading.patch} | 0 ...ferfish-Dynamic-Activation-of-Brain.patch} | 0 ...le-goal-selector-during-inactive-ti.patch} | 0 ...ufferfish-Reduce-entity-allocations.patch} | 0 ...le-Variable-entity-wake-up-duration.patch} | 0 ...hunks-to-activate-climbing-entities.patch} | 2 +- ...=> 0043-Gale-Optimize-sun-burn-tick.patch} | 0 ...k-frozen-ticks-before-landing-block.patch} | 2 +- ...r-lootable-refresh-for-non-player-i.patch} | 2 +- ...46-Gale-Use-platform-math-functions.patch} | 0 ...kip-entity-move-if-movement-is-zero.patch} | 0 ...ld-generation-chunk-and-block-acces.patch} | 0 ...0049-Gale-Optimize-noise-generation.patch} | 0 ...050-Gale-Faster-chunk-serialization.patch} | 0 ...er-Remove-all-locks-on-region-files.patch} | 0 ...parkly-Paper-Optimize-canSee-checks.patch} | 2 +- ...3-Purpur-use-alternative-keep-alive.patch} | 8 +- ....patch => 0054-Leaves-Protocol-Core.patch} | 10 +- ...ch => 0055-Leaves-Bladeren-Protocol.patch} | 0 ...> 0056-Leaves-Fix-Bladeren-Protocol.patch} | 0 ...0057-Leaves-carpet-protocol-support.patch} | 0 ...-start-tick-and-finished-tick-event.patch} | 0 44 files changed, 274 insertions(+), 17 deletions(-) create mode 100644 patches/server/0015-Add-a-simple-watchdog-for-tick-regions.patch rename patches/server/{0015-Io_uring-channel-type-support.patch => 0016-Io_uring-channel-type-support.patch} (100%) rename patches/server/{0016-Try-fixing-folia-spector-teleportation.patch => 0017-Try-fixing-folia-spector-teleportation.patch} (100%) rename patches/server/{0017-Teleport-async-if-entity-was-moving-to-another-regio.patch => 0018-Teleport-async-if-entity-was-moving-to-another-regio.patch} (100%) rename patches/server/{0018-Prevent-teleportAsync-calling-during-moving-event-be.patch => 0019-Prevent-teleportAsync-calling-during-moving-event-be.patch} (100%) rename patches/server/{0019-Piston-fixes-from-molean-server.patch => 0020-Piston-fixes-from-molean-server.patch} (100%) rename patches/server/{0020-Kaiiju-linear-region-format-and-settings.patch => 0021-Kaiiju-linear-region-format-and-settings.patch} (99%) rename patches/server/{0021-Kaiiju-Don-t-pathfind-outside-region.patch => 0022-Kaiiju-Don-t-pathfind-outside-region.patch} (100%) rename patches/server/{0022-Kaiiju-Vanilla-end-portal-teleportation.patch => 0023-Kaiiju-Vanilla-end-portal-teleportation.patch} (100%) rename patches/server/{0023-Kaiiju-Async-path-processing.patch => 0024-Kaiiju-Async-path-processing.patch} (100%) rename patches/server/{0024-Petal-Reduce-sensor-work.patch => 0025-Petal-Reduce-sensor-work.patch} (100%) rename patches/server/{0025-Pufferfish-Optimize-entity-coordinate-key.patch => 0026-Pufferfish-Optimize-entity-coordinate-key.patch} (100%) rename patches/server/{0026-Pufferfish-Cache-climbing-check-for-activation.patch => 0027-Pufferfish-Cache-climbing-check-for-activation.patch} (96%) rename patches/server/{0027-Pufferfish-Improve-fluid-direction-caching.patch => 0028-Pufferfish-Improve-fluid-direction-caching.patch} (100%) rename patches/server/{0028-Pufferfish-Optimize-suffocation.patch => 0029-Pufferfish-Optimize-suffocation.patch} (97%) rename patches/server/{0029-Pufferfish-Early-return-optimization-for-target-find.patch => 0030-Pufferfish-Early-return-optimization-for-target-find.patch} (100%) rename patches/server/{0030-Pufferfish-Reduce-chunk-loading-lookups.patch => 0031-Pufferfish-Reduce-chunk-loading-lookups.patch} (100%) rename patches/server/{0031-Pufferfish-Improve-container-checking-with-a-bitset.patch => 0032-Pufferfish-Improve-container-checking-with-a-bitset.patch} (99%) rename patches/server/{0032-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch => 0033-Pufferfish-Fix-Paper-6045-block-goal-shouldn-t-load-.patch} (100%) rename patches/server/{0033-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch => 0034-Pufferfish-Reduce-entity-fluid-lookups-if-no-fluids.patch} (100%) rename patches/server/{0034-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch => 0035-Pufferfish-Only-check-for-spooky-season-once-an-hour.patch} (100%) rename patches/server/{0035-Pufferfish-Entity-TTL.patch => 0036-Pufferfish-Entity-TTL.patch} (100%) rename patches/server/{0036-Pufferfish-Reduce-projectile-chunk-loading.patch => 0037-Pufferfish-Reduce-projectile-chunk-loading.patch} (100%) rename patches/server/{0037-Pufferfish-Dynamic-Activation-of-Brain.patch => 0038-Pufferfish-Dynamic-Activation-of-Brain.patch} (100%) rename patches/server/{0038-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch => 0039-Pufferfish-Throttle-goal-selector-during-inactive-ti.patch} (100%) rename patches/server/{0039-Pufferfish-Reduce-entity-allocations.patch => 0040-Pufferfish-Reduce-entity-allocations.patch} (100%) rename patches/server/{0040-Gale-Variable-entity-wake-up-duration.patch => 0041-Gale-Variable-entity-wake-up-duration.patch} (100%) rename patches/server/{0041-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch => 0042-Gale-Don-t-load-chunks-to-activate-climbing-entities.patch} (97%) rename patches/server/{0042-Gale-Optimize-sun-burn-tick.patch => 0043-Gale-Optimize-sun-burn-tick.patch} (100%) rename patches/server/{0043-Gale-Check-frozen-ticks-before-landing-block.patch => 0044-Gale-Check-frozen-ticks-before-landing-block.patch} (93%) rename patches/server/{0044-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch => 0045-Gale-Don-t-trigger-lootable-refresh-for-non-player-i.patch} (92%) rename patches/server/{0045-Gale-Use-platform-math-functions.patch => 0046-Gale-Use-platform-math-functions.patch} (100%) rename patches/server/{0046-Gale-Skip-entity-move-if-movement-is-zero.patch => 0047-Gale-Skip-entity-move-if-movement-is-zero.patch} (100%) rename patches/server/{0047-Gale-Optimize-world-generation-chunk-and-block-acces.patch => 0048-Gale-Optimize-world-generation-chunk-and-block-acces.patch} (100%) rename patches/server/{0048-Gale-Optimize-noise-generation.patch => 0049-Gale-Optimize-noise-generation.patch} (100%) rename patches/server/{0049-Gale-Faster-chunk-serialization.patch => 0050-Gale-Faster-chunk-serialization.patch} (100%) rename patches/server/{0050-LinearPaper-Remove-all-locks-on-region-files.patch => 0051-LinearPaper-Remove-all-locks-on-region-files.patch} (100%) rename patches/server/{0051-Sparkly-Paper-Optimize-canSee-checks.patch => 0052-Sparkly-Paper-Optimize-canSee-checks.patch} (97%) rename patches/server/{0052-Purpur-use-alternative-keep-alive.patch => 0053-Purpur-use-alternative-keep-alive.patch} (94%) rename patches/server/{0053-Leaves-Protocol-Core.patch => 0054-Leaves-Protocol-Core.patch} (98%) rename patches/server/{0054-Leaves-Bladeren-Protocol.patch => 0055-Leaves-Bladeren-Protocol.patch} (100%) rename patches/server/{0055-Leaves-Fix-Bladeren-Protocol.patch => 0056-Leaves-Fix-Bladeren-Protocol.patch} (100%) rename patches/server/{0056-Leaves-carpet-protocol-support.patch => 0057-Leaves-carpet-protocol-support.patch} (100%) rename patches/server/{0057-Threaded-region-start-tick-and-finished-tick-event.patch => 0058-Threaded-region-start-tick-and-finished-tick-event.patch} (100%) diff --git a/patches/server/0015-Add-a-simple-watchdog-for-tick-regions.patch b/patches/server/0015-Add-a-simple-watchdog-for-tick-regions.patch new file mode 100644 index 0000000..44cb370 --- /dev/null +++ b/patches/server/0015-Add-a-simple-watchdog-for-tick-regions.patch @@ -0,0 +1,257 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MrHua269 +Date: Sun, 10 Mar 2024 05:04:33 +0000 +Subject: [PATCH] Add a simple watchdog for tick regions + + +diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java +index fc3d332aa1c1d469cedfe2aaa7102dcd78e25642..1ae61bc6603dd3ac290e3ead20416f9c5b63ff02 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java ++++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java +@@ -279,6 +279,7 @@ public final class RegionizedServer { + */ + + private void globalTick(final int tickCount) { ++ me.earthme.luminol.utils.LuminolWatchDog.globalRegionHeartBeat(); //Luminol + /* + if (false) { + io.papermc.paper.threadedregions.ThreadedTicketLevelPropagator.main(null); +diff --git a/src/main/java/io/papermc/paper/threadedregions/ThreadedRegionizer.java b/src/main/java/io/papermc/paper/threadedregions/ThreadedRegionizer.java +index 531aa50f2c84e13358e8918bb0c15ea3cd036cb5..fd0053369eb68f0fd596d8acfba4a5247ef8105a 100644 +--- a/src/main/java/io/papermc/paper/threadedregions/ThreadedRegionizer.java ++++ b/src/main/java/io/papermc/paper/threadedregions/ThreadedRegionizer.java +@@ -167,6 +167,8 @@ public final class ThreadedRegionizer globalRegionLastKeepalive = null; ++ private static final Map,Long>> otherTickRegionKeepalive = Maps.newHashMap(); ++ private static final Executor checkTimer = CompletableFuture.delayedExecutor(50, TimeUnit.MILLISECONDS); ++ private static final Logger logger = MinecraftServer.LOGGER; ++ private static int tickCount = 0; ++ private static boolean runScheduleNext = true; ++ ++ public static void boot(){ ++ runCheck(); ++ } ++ ++ private static void scheduleCheck(){ ++ checkTimer.execute(LuminolWatchDog::runCheck); ++ } ++ ++ private static void runCheck(){ ++ try { ++ if (MinecraftServer.getServer().isStopped() || !runScheduleNext){ ++ return; ++ } ++ ++ tickCount++; ++ ++ final List> threadsToWarn = new ArrayList<>(); ++ final long currentTimeNano = System.nanoTime(); ++ boolean shouldStopServer = false; ++ ++ synchronized (keepaliveDataLock){ ++ if (globalRegionLastKeepalive != null){ ++ final Thread lastGlobalRegionThread = globalRegionLastKeepalive.getLeft(); ++ final long lastTicked = globalRegionLastKeepalive.getRight(); ++ ++ final long timeEscaped = currentTimeNano - lastTicked; ++ ++ if (timeEscaped >= WatchdogConfig.warnPeriodTicks * 50 * 1000 * 1000){ ++ threadsToWarn.add(Pair.of(lastGlobalRegionThread,timeEscaped)); ++ } ++ } ++ ++ for(Pair warnInfo : threadsToWarn){ ++ final Thread targetThread = warnInfo.getLeft(); ++ final long timeEscaped = warnInfo.getRight(); ++ ++ final ThreadedRegionizer.ThreadedRegion targetRegion; ++ ++ synchronized (keepaliveDataLock){ ++ targetRegion = otherTickRegionKeepalive.get(targetThread).getLeft(); ++ } ++ ++ if (tickCount % WatchdogConfig.warnPeriodTicks == 0){ ++ dumpSingleRegion(targetThread,targetRegion,timeEscaped); ++ } ++ ++ if (timeEscaped > WatchdogConfig.timeOutTicks * 50 * 1000 * 1000){ ++ shouldStopServer = true; ++ runScheduleNext = false; ++ } ++ } ++ ++ if (shouldStopServer){ ++ MinecraftServer.getServer().stopServer(); ++ } ++ } ++ }finally { ++ if (runScheduleNext){ ++ scheduleCheck(); ++ } ++ } ++ } ++ ++ private static void dumpSingleRegion(@NotNull Thread thread, @Nullable ThreadedRegionizer.ThreadedRegion region,long timeEscaped){ ++ final StringBuilder messageBuilder = new StringBuilder(); ++ messageBuilder.append("====================================").append("\n"); ++ messageBuilder.append("There is a single region that has no responding in " + TimeUnit.NANOSECONDS.toSeconds(timeEscaped) + " seconds!").append("\n"); ++ messageBuilder.append("If you believe this is a bug,please send it to github issue after checking your plugins!").append("\n"); ++ messageBuilder.append("Tick Region: ").append(region == null ? "Global Region" : "ChunkX(Center): " + region.getCenterChunk().x + " ChunkZ(Center): " + region.getCenterChunk().z).append("\n"); ++ messageBuilder.append("Thread Name: ").append(thread.getName()).append("\n"); ++ messageBuilder.append("Thread Id: ").append(thread.getId()).append("\n"); ++ ++ final ThreadInfo targetThreadInfo = ManagementFactory.getThreadMXBean().getThreadInfo(thread.getId()); ++ ++ messageBuilder.append("Is Suspend: ").append(targetThreadInfo.isSuspended()).append("\n"); ++ messageBuilder.append("Thread State: ").append(targetThreadInfo.getThreadState()).append("\n"); ++ messageBuilder.append("Thread Priority: ").append(targetThreadInfo.getPriority()).append("\n"); ++ messageBuilder.append("Thread Stack Trace:").append("\n"); ++ ++ for (StackTraceElement stackTraceElement : StacktraceDeobfuscator.INSTANCE.deobfuscateStacktrace(thread.getStackTrace())){ ++ messageBuilder.append("\t\t").append(stackTraceElement).append("\n"); ++ } ++ ++ messageBuilder.append("\n"); ++ messageBuilder.append("===================================="); ++ ++ logger.error(messageBuilder.toString()); ++ } ++ ++ public static void globalRegionHeartBeat(){ ++ if (!WatchdogConfig.enabled){ ++ return; ++ } ++ ++ synchronized (keepaliveDataLock){ ++ globalRegionLastKeepalive = Pair.of(Thread.currentThread(),System.nanoTime()); ++ } ++ } ++ ++ public static void tickRegionHeartBeat(){ ++ if (!WatchdogConfig.enabled){ ++ return; ++ } ++ ++ final ThreadedRegionizer.ThreadedRegion currentRegion = TickRegionScheduler.getCurrentRegion(); ++ ++ if (currentRegion == null) { ++ return; ++ } ++ ++ synchronized (keepaliveDataLock){ ++ if (!otherTickRegionKeepalive.containsKey(Thread.currentThread())){ ++ otherTickRegionKeepalive.put(Thread.currentThread(),Pair.of(currentRegion,System.nanoTime())); ++ return; ++ } ++ ++ otherTickRegionKeepalive.replace(Thread.currentThread(),Pair.of(currentRegion,System.nanoTime())); ++ } ++ } ++ ++ public static void onRegionDeath(ThreadedRegionizer.ThreadedRegion currentRegion){ ++ if (!WatchdogConfig.enabled){ ++ return; ++ } ++ ++ synchronized (keepaliveDataLock){ ++ otherTickRegionKeepalive.remove(Thread.currentThread()); ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index dd4fbe5a51e05560343d2ee919d4bc50963e3d70..4d3ba2b02d19cc43a19bc633b9c5df66b85533f7 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1222,6 +1222,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop packCallbacks = new java.util.concurrent.ConcurrentHashMap<>(); // Paper - adventure resource pack callbacks -@@ -105,6 +106,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -103,6 +104,16 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleKeepAlive(ServerboundKeepAlivePacket packet) { @@ -59,7 +59,7 @@ index 43c8e48ecdf82a17b81fc91c6f602c953067d11c..38564ab781665aeb215734a367bc8727 //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // CraftBukkit // Paper - handle ServerboundKeepAlivePacket async if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) { int i = (int) (Util.getMillis() - this.keepAliveTime); -@@ -225,6 +236,21 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -221,6 +232,21 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack long currentTime = Util.getMillis(); long elapsedTime = currentTime - this.keepAliveTime; diff --git a/patches/server/0053-Leaves-Protocol-Core.patch b/patches/server/0054-Leaves-Protocol-Core.patch similarity index 98% rename from patches/server/0053-Leaves-Protocol-Core.patch rename to patches/server/0054-Leaves-Protocol-Core.patch index cd12769..5d93b2e 100644 --- a/patches/server/0053-Leaves-Protocol-Core.patch +++ b/patches/server/0054-Leaves-Protocol-Core.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Leaves Protocol Core diff --git a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java -index fc3d332aa1c1d469cedfe2aaa7102dcd78e25642..bebaa4e7abcbd01dc57fddf2a473b846e887cc7f 100644 +index 1ae61bc6603dd3ac290e3ead20416f9c5b63ff02..168ed2c21aed6a10f3aca259880b1b8bdbf98b78 100644 --- a/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java +++ b/src/main/java/io/papermc/paper/threadedregions/RegionizedServer.java -@@ -313,6 +313,8 @@ public final class RegionizedServer { +@@ -314,6 +314,8 @@ public final class RegionizedServer { // player list MinecraftServer.getServer().getPlayerList().tick(); @@ -36,10 +36,10 @@ index af86f752c33a2990405fea058b7c41c437ba9d46..bada9fae1e7178162429e1f5a1608b9c } diff --git a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -index 38564ab781665aeb215734a367bc87271efd3d2a..f8ebb4349004e67d399e44588e159528d31c7be0 100644 +index c68910b2a2eb703406fb406a86783cf6ab48651e..f935214ed80fe54038a96a5cd668a072cdf406ec 100644 --- a/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -141,6 +141,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -139,6 +139,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack @Override public void handleCustomPayload(ServerboundCustomPayloadPacket packet) { @@ -47,7 +47,7 @@ index 38564ab781665aeb215734a367bc87271efd3d2a..f8ebb4349004e67d399e44588e159528 // Paper start - Brand support if (packet.payload() instanceof net.minecraft.network.protocol.common.custom.BrandPayload brandPayload) { this.player.clientBrandName = brandPayload.brand(); -@@ -160,6 +161,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack +@@ -156,6 +157,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack String channels = payload.toString(com.google.common.base.Charsets.UTF_8); for (String channel : channels.split("\0")) { this.getCraftPlayer().addChannel(channel); diff --git a/patches/server/0054-Leaves-Bladeren-Protocol.patch b/patches/server/0055-Leaves-Bladeren-Protocol.patch similarity index 100% rename from patches/server/0054-Leaves-Bladeren-Protocol.patch rename to patches/server/0055-Leaves-Bladeren-Protocol.patch diff --git a/patches/server/0055-Leaves-Fix-Bladeren-Protocol.patch b/patches/server/0056-Leaves-Fix-Bladeren-Protocol.patch similarity index 100% rename from patches/server/0055-Leaves-Fix-Bladeren-Protocol.patch rename to patches/server/0056-Leaves-Fix-Bladeren-Protocol.patch diff --git a/patches/server/0056-Leaves-carpet-protocol-support.patch b/patches/server/0057-Leaves-carpet-protocol-support.patch similarity index 100% rename from patches/server/0056-Leaves-carpet-protocol-support.patch rename to patches/server/0057-Leaves-carpet-protocol-support.patch diff --git a/patches/server/0057-Threaded-region-start-tick-and-finished-tick-event.patch b/patches/server/0058-Threaded-region-start-tick-and-finished-tick-event.patch similarity index 100% rename from patches/server/0057-Threaded-region-start-tick-and-finished-tick-event.patch rename to patches/server/0058-Threaded-region-start-tick-and-finished-tick-event.patch