Add integrated server watchdog
This commit is contained in:
parent
3b56f00b82
commit
10149e9f87
|
|
@ -20,11 +20,15 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
|
|||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.embeddedt.modernfix.core.config.ModernFixConfig;
|
||||
import org.embeddedt.modernfix.load.LoadEvents;
|
||||
import org.embeddedt.modernfix.packet.EntityIDSyncPacket;
|
||||
import org.embeddedt.modernfix.screen.DeferredLevelLoadingScreen;
|
||||
import org.embeddedt.modernfix.world.IntegratedWatchdog;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
|
|
@ -219,4 +223,13 @@ public class ModernFixClient {
|
|||
|
||||
context.get().setPacketHandled(true);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarted(FMLServerStartingEvent event) {
|
||||
if(ModernFixConfig.INTEGRATED_SERVER_WATCHDOG.get()) {
|
||||
IntegratedWatchdog watchdog = new IntegratedWatchdog(event.getServer());
|
||||
watchdog.start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public class ModernFixConfig {
|
|||
public static ForgeConfigSpec.BooleanValue ENABLE_DEBUG_RELOADER;
|
||||
|
||||
public static ForgeConfigSpec.BooleanValue REBUILD_BLOCKSTATES_ASYNC;
|
||||
public static ForgeConfigSpec.BooleanValue INTEGRATED_SERVER_WATCHDOG;
|
||||
|
||||
public static Set<ResourceLocation> jeiPluginBlacklist;
|
||||
|
||||
|
|
@ -43,6 +44,9 @@ public class ModernFixConfig {
|
|||
REBUILD_BLOCKSTATES_ASYNC = COMMON_BUILDER
|
||||
.comment("Rebuild blockstate cache asynchronously. Should work with most mods, but can be disabled.")
|
||||
.define("rebuild_blockstate_cache_async", true);
|
||||
INTEGRATED_SERVER_WATCHDOG = COMMON_BUILDER
|
||||
.comment("Automatically output a thread dump if the integrated server spends too long on one tick")
|
||||
.define("integrated_server_watchdog", true);
|
||||
}
|
||||
|
||||
static {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
package org.embeddedt.modernfix.world;
|
||||
|
||||
import net.minecraft.DefaultUncaughtExceptionHandlerWithName;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class IntegratedWatchdog extends Thread {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private final MinecraftServer server;
|
||||
|
||||
private static final long MAX_TICK_DELTA = 40*1000;
|
||||
|
||||
public IntegratedWatchdog(MinecraftServer server) {
|
||||
this.server = server;
|
||||
this.setDaemon(true);
|
||||
this.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandlerWithName(LOGGER));
|
||||
this.setName("ModernFix integrated server watchdog");
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while(server.isRunning()) {
|
||||
long nextTick = this.server.getNextTickTime();
|
||||
long curTime = Util.getMillis();
|
||||
if((curTime - nextTick) > MAX_TICK_DELTA) {
|
||||
LOGGER.error("A single server tick has taken {}, more than {} milliseconds", (nextTick - curTime), MAX_TICK_DELTA);
|
||||
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
|
||||
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Thread Dump:\n");
|
||||
for(ThreadInfo threadinfo : athreadinfo) {
|
||||
sb.append(threadinfo);
|
||||
StackTraceElement[] elements = threadinfo.getStackTrace();
|
||||
if(elements.length > 8) {
|
||||
sb.append("extended trace:\n");
|
||||
for(int i = 8; i < elements.length; i++) {
|
||||
sb.append("\tat ");
|
||||
sb.append(elements[i]);
|
||||
sb.append('\n');
|
||||
}
|
||||
}
|
||||
sb.append('\n');
|
||||
}
|
||||
LOGGER.error(sb);
|
||||
nextTick = 0;
|
||||
curTime = 0;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(nextTick + MAX_TICK_DELTA - curTime);
|
||||
} catch(InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user