ServerWatchdog.java
net.minecraft.server.dedicated.ServerWatchdog
信息
- 全限定名:net.minecraft.server.dedicated.ServerWatchdog
- 类型:public class
- 包:net.minecraft.server.dedicated
- 源码路径:src/main/java/net/minecraft/server/dedicated/ServerWatchdog.java
- 起始行号:L23
- 实现:Runnable
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L24 - 说明:
TODO
- 类型:
-
MAX_SHUTDOWN_TIME- 类型:
long - 修饰符:
private static final - 源码定位:
L25 - 说明:
TODO
- 类型:
-
SHUTDOWN_STATUS- 类型:
int - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
server- 类型:
DedicatedServer - 修饰符:
private final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
maxTickTimeNanos- 类型:
long - 修饰符:
private final - 源码定位:
L28 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
public ServerWatchdog(DedicatedServer server) @ L30
- 构造器名:ServerWatchdog
- 源码定位:L30
- 修饰符:public
参数:
- server: DedicatedServer
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void run() @ L35
- 方法名:run
- 源码定位:L35
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public static CrashReport createWatchdogCrashReport(String message, long mainThreadId) @ L77
- 方法名:createWatchdogCrashReport
- 源码定位:L77
- 返回类型:CrashReport
- 修饰符:public static
参数:
- message: String
- mainThreadId: long
说明:
TODO
private void exit() @ L98
- 方法名:exit
- 源码定位:L98
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
代码
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 server) {
this.server = server;
this.maxTickTimeNanos = server.getMaxTickLength() * TimeUtil.NANOSECONDS_PER_MILLISECOND;
}
@Override
public void run() {
while (this.server.isRunning()) {
long nextTickTimeNanos = this.server.getNextTickTime();
long currentTimeNanos = Util.getNanos();
long deltaNanos = currentTimeNanos - nextTickTimeNanos;
if (deltaNanos > this.maxTickTimeNanos) {
LOGGER.error(
LogUtils.FATAL_MARKER,
"A single server tick took {} seconds (should be max {})",
String.format(Locale.ROOT, "%.2f", (float)deltaNanos / (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 report = createWatchdogCrashReport("Watching Server", this.server.getRunningThread().threadId());
this.server.fillSystemReport(report.getSystemReport());
CrashReportCategory serverStats = report.addCategory("Performance stats");
serverStats.setDetail("Random tick rate", () -> this.server.getGameRules().getAsString(GameRules.RANDOM_TICK_SPEED));
serverStats.setDetail(
"Level stats",
() -> Streams.stream(this.server.getAllLevels())
.map(level -> level.dimension().identifier() + ": " + level.getWatchdogStats())
.collect(Collectors.joining(",\n"))
);
Bootstrap.realStdoutPrintln("Crash report:\n" + report.getFriendlyReport(ReportType.CRASH));
Path file = this.server.getServerDirectory().resolve("crash-reports").resolve("crash-" + Util.getFilenameFormattedDateTime() + "-server.txt");
if (report.saveToFile(file, ReportType.CRASH)) {
LOGGER.error("This crash report has been saved to: {}", file.toAbsolutePath());
} else {
LOGGER.error("We were unable to save this crash report to disk.");
}
this.exit();
}
try {
Thread.sleep((nextTickTimeNanos + this.maxTickTimeNanos - currentTimeNanos) / TimeUtil.NANOSECONDS_PER_MILLISECOND);
} catch (InterruptedException var10) {
}
}
}
public static CrashReport createWatchdogCrashReport(String message, long mainThreadId) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(true, true);
StringBuilder builder = new StringBuilder();
Error exception = new Error("Watchdog");
for (ThreadInfo threadInfo : threadInfos) {
if (threadInfo.getThreadId() == mainThreadId) {
exception.setStackTrace(threadInfo.getStackTrace());
}
builder.append(threadInfo);
builder.append("\n");
}
CrashReport report = new CrashReport(message, exception);
CrashReportCategory threadDump = report.addCategory("Thread Dump");
threadDump.setDetail("Threads", builder);
return report;
}
private void exit() {
try {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
{
Objects.requireNonNull(ServerWatchdog.this);
}
@Override
public void run() {
Runtime.getRuntime().halt(1);
}
}, 10000L);
System.exit(1);
} catch (Throwable var2) {
Runtime.getRuntime().halt(1);
}
}
}引用的其他类
-
- 引用位置:
构造调用 - 关联成员:
Error()
- 引用位置:
-
- 引用位置:
构造调用/返回值 - 关联成员:
CrashReport()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
Timer()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
System.exit()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Bootstrap.realStdoutPrintln()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getFilenameFormattedDateTime(), Util.getNanos()
- 引用位置: