mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-30 06:24:06 +01:00
fb2c24b36d
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 05ae036c PR-746: Add option to use cached map color palette 57849c1b PR-759: Add preview chat option in ServerListPingEvent 0169e65d PR-758: Add missing server properties methods from 1.19 CraftBukkit Changes: 622dbe6c2 SPIGOT-7068: SKULK and SKULK_VEIN BlockSpreadEvents Still do not reference the correct source (SKULK_CATALYST) 6c61b73f3 PR-1052: Add option to use cached map color palette c882f38ea SPIGOT-7066: Fix custom END worlds not generating DragonBattle 6866aab59 SPIGOT-2420: Can't set exp drops for EnderDragon death 9dcd46530 PR-1067: Add preview chat option in ServerListPingEvent 36c2681af PR-1066: Add missing server properties methods from 1.19 031eaadd0 Increase outdated build delay 8fda4b12f SPIGOT-7060: SCULK and SCULK_VEIN BlockSpreadEvents do not reference the correct source
160 lines
9.6 KiB
Diff
160 lines
9.6 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: miclebrick <miclebrick@outlook.com>
|
|
Date: Wed, 8 Aug 2018 15:30:52 -0400
|
|
Subject: [PATCH] Add Early Warning Feature to WatchDog
|
|
|
|
Detect when the server has been hung for a long duration, and start printing
|
|
thread dumps at an interval until the point of crash.
|
|
|
|
This will help diagnose what was going on in that time before the crash.
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index f532aba1f180f0c86b4360bb85993732207b2345..e3f43c2b6ff47f6a8c158d176dfc2c5a3fa66a62 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -1057,6 +1057,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
this.updateStatusIcon(this.status);
|
|
|
|
// Spigot start
|
|
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
|
Arrays.fill( recentTps, 20 );
|
|
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
|
lastTick = start - TICK_TIME; // Paper
|
|
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
index b248c0f481436b1b101dc1f75eaaf8023f4ba0ea..02ea5304a3f99d69005ab1a7ea85e6a13009fa89 100644
|
|
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
|
@@ -202,6 +202,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
|
// Paper start
|
|
paperConfigurations.initializeGlobalConfiguration();
|
|
paperConfigurations.initializeWorldDefaultsConfiguration();
|
|
+ org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash);
|
|
io.papermc.paper.command.PaperCommands.registerCommands(this);
|
|
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
|
|
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index 53834d226cf577413d1514c54f5a4b0294a432e7..3ffb9cb08dc3b71662364bd5553b895ddc0f9ab7 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -907,6 +907,7 @@ public final class CraftServer implements Server {
|
|
|
|
@Override
|
|
public void reload() {
|
|
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
|
this.reloadCount++;
|
|
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
|
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
|
|
@@ -995,6 +996,7 @@ public final class CraftServer implements Server {
|
|
this.enablePlugins(PluginLoadOrder.STARTUP);
|
|
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
|
this.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
|
|
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
|
index 645643d102118ad4916a152abfb9ab0d02751e11..edc5f195cc3de8885b839469656650ba465346be 100644
|
|
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
|
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
|
@@ -229,7 +229,7 @@ public class SpigotConfig
|
|
SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript );
|
|
SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) );
|
|
SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) );
|
|
- WatchdogThread.doStart( timeoutTime, restartOnCrash );
|
|
+ // WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to after paper config initialization
|
|
}
|
|
|
|
public static boolean bungee;
|
|
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
|
index 6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529..06efdd7aa6d35a670e81c4f303618a7ba301396a 100644
|
|
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
|
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
|
@@ -14,6 +14,10 @@ public class WatchdogThread extends Thread
|
|
private static WatchdogThread instance;
|
|
private long timeoutTime;
|
|
private boolean restart;
|
|
+ private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
|
+ private final long earlyWarningDelay; // Paper
|
|
+ public static volatile boolean hasStarted; // Paper
|
|
+ private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
|
private volatile long lastTick;
|
|
private volatile boolean stopping;
|
|
|
|
@@ -22,6 +26,8 @@ public class WatchdogThread extends Thread
|
|
super( "Paper Watchdog Thread" );
|
|
this.timeoutTime = timeoutTime;
|
|
this.restart = restart;
|
|
+ earlyWarningEvery = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper
|
|
+ earlyWarningDelay = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningDelay, timeoutTime); // Paper
|
|
}
|
|
|
|
private static long monotonicMillis()
|
|
@@ -61,9 +67,18 @@ public class WatchdogThread extends Thread
|
|
while ( !this.stopping )
|
|
{
|
|
//
|
|
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
|
+ // Paper start
|
|
+ Logger log = Bukkit.getServer().getLogger();
|
|
+ long currentTime = WatchdogThread.monotonicMillis();
|
|
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
|
{
|
|
- Logger log = Bukkit.getServer().getLogger();
|
|
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
|
+ // Don't spam early warning dumps
|
|
+ if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
|
|
+ if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
|
|
+ lastEarlyWarning = currentTime;
|
|
+ if (isLongTimeout) {
|
|
+ // Paper end
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
|
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
|
@@ -93,29 +108,45 @@ public class WatchdogThread extends Thread
|
|
}
|
|
}
|
|
// Paper end
|
|
+ } else
|
|
+ {
|
|
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---");
|
|
+ log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump");
|
|
+ }
|
|
+ // Paper end - Different message for short timeout
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
|
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
//
|
|
+ // Paper start - Only print full dump on long timeouts
|
|
+ if ( isLongTimeout )
|
|
+ {
|
|
log.log( Level.SEVERE, "Entire Thread Dump:" );
|
|
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
|
for ( ThreadInfo thread : threads )
|
|
{
|
|
WatchdogThread.dumpThread( thread, log );
|
|
}
|
|
+ } else {
|
|
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
|
|
+ }
|
|
+
|
|
log.log( Level.SEVERE, "------------------------------" );
|
|
|
|
+ if ( isLongTimeout )
|
|
+ {
|
|
if ( this.restart && !MinecraftServer.getServer().hasStopped() )
|
|
{
|
|
RestartCommand.restart();
|
|
}
|
|
break;
|
|
+ } // Paper end
|
|
}
|
|
|
|
try
|
|
{
|
|
- sleep( 10000 );
|
|
+ sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
|
} catch ( InterruptedException ex )
|
|
{
|
|
interrupt();
|