soiz1's picture
Upload folder using huggingface_hub
d46f4a3 verified
package net.minecraft.server.dedicated;
import com.google.common.collect.Streams;
import com.mojang.logging.LogUtils;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
import java.util.stream.Collectors;
import net.minecraft.CrashReport;
import net.minecraft.CrashReportCategory;
import net.minecraft.ReportType;
import net.minecraft.Util;
import net.minecraft.server.Bootstrap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.TimeUtil;
import net.minecraft.world.level.GameRules;
import org.slf4j.Logger;
public class ServerWatchdog implements Runnable {
private static final Logger LOGGER = LogUtils.getLogger();
private static final long MAX_SHUTDOWN_TIME = 10000L;
private static final int SHUTDOWN_STATUS = 1;
private final DedicatedServer server;
private final long maxTickTimeNanos;
public ServerWatchdog(DedicatedServer p_139786_) {
this.server = p_139786_;
this.maxTickTimeNanos = p_139786_.getMaxTickLength() * TimeUtil.NANOSECONDS_PER_MILLISECOND;
}
@Override
public void run() {
while (this.server.isRunning()) {
long i = this.server.getNextTickTime();
long j = Util.getNanos();
long k = j - i;
if (k > this.maxTickTimeNanos) {
LOGGER.error(
LogUtils.FATAL_MARKER,
"A single server tick took {} seconds (should be max {})",
String.format(Locale.ROOT, "%.2f", (float)k / (float)TimeUtil.NANOSECONDS_PER_SECOND),
String.format(Locale.ROOT, "%.2f", this.server.tickRateManager().millisecondsPerTick() / (float)TimeUtil.MILLISECONDS_PER_SECOND)
);
LOGGER.error(LogUtils.FATAL_MARKER, "Considering it to be crashed, server will forcibly shutdown.");
CrashReport crashreport = createWatchdogCrashReport("Watching Server", this.server.getRunningThread().threadId());
this.server.fillSystemReport(crashreport.getSystemReport());
CrashReportCategory crashreportcategory = crashreport.addCategory("Performance stats");
crashreportcategory.setDetail("Random tick rate", () -> this.server.getWorldData().getGameRules().getRule(GameRules.RULE_RANDOMTICKING).toString());
crashreportcategory.setDetail(
"Level stats",
() -> Streams.stream(this.server.getAllLevels())
.map(p_374881_ -> p_374881_.dimension().location() + ": " + p_374881_.getWatchdogStats())
.collect(Collectors.joining(",\n"))
);
Bootstrap.realStdoutPrintln("Crash report:\n" + crashreport.getFriendlyReport(ReportType.CRASH));
Path path = this.server.getServerDirectory().resolve("crash-reports").resolve("crash-" + Util.getFilenameFormattedDateTime() + "-server.txt");
if (crashreport.saveToFile(path, ReportType.CRASH)) {
LOGGER.error("This crash report has been saved to: {}", path.toAbsolutePath());
} else {
LOGGER.error("We were unable to save this crash report to disk.");
}
this.exit();
}
try {
Thread.sleep((i + this.maxTickTimeNanos - j) / TimeUtil.NANOSECONDS_PER_MILLISECOND);
} catch (InterruptedException interruptedexception) {
}
}
}
public static CrashReport createWatchdogCrashReport(String p_362648_, long p_368427_) {
ThreadMXBean threadmxbean = ManagementFactory.getThreadMXBean();
ThreadInfo[] athreadinfo = threadmxbean.dumpAllThreads(true, true);
StringBuilder stringbuilder = new StringBuilder();
Error error = new Error("Watchdog");
for (ThreadInfo threadinfo : athreadinfo) {
if (threadinfo.getThreadId() == p_368427_) {
error.setStackTrace(threadinfo.getStackTrace());
}
stringbuilder.append(threadinfo);
stringbuilder.append("\n");
}
CrashReport crashreport = new CrashReport(p_362648_, error);
CrashReportCategory crashreportcategory = crashreport.addCategory("Thread Dump");
crashreportcategory.setDetail("Threads", stringbuilder);
return crashreport;
}
private void exit() {
try {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Runtime.getRuntime().halt(1);
}
}, 10000L);
System.exit(1);
} catch (Throwable throwable) {
Runtime.getRuntime().halt(1);
}
}
}