Many improvements to chunk prioritization and bug fixes

Fixed a few bugs, and made numerous improvements.
Fixed issue where a sync chunk load could have its ticket removed and the
priority ticket could expire...
Still not perfect there but better than before.

Also fixed few other misc issues such as watchdog cpu usage, chunk queue update
had risk of double enqueue due to it no longer being a set.

Added much more information about chunk state to watchdog prints.

I see some more room for improvement even, but this is much better than before.

Fixes #3407
Fixes #3411
Fixes #3395
Fixes #3389
This commit is contained in:
Aikar
2020-05-20 05:11:57 -04:00
parent ade297307f
commit 33246e0ba0
8 changed files with 247 additions and 73 deletions

View File

@@ -160,6 +160,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
}
public static Timing getTickList(WorldServer worldserver, String timingsType) {
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperCommand.java
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +0,0 @@
package com.destroystokyo.paper;
+import com.destroystokyo.paper.io.chunk.ChunkTaskManager;
import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
public PaperCommand(String name) {
super(name);
this.description = "Paper related commands";
- this.usageMessage = "/paper [heap | entity | reload | version | debug | chunkinfo]";
+ this.usageMessage = "/paper [heap | entity | reload | version | debug | dumpwaiting | chunkinfo]";
this.setPermission("bukkit.command.paper");
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
if (args.length <= 1)
- return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "chunkinfo");
+ return getListMatchingLast(args, "heap", "entity", "reload", "version", "debug", "dumpwaiting", "chunkinfo");
switch (args[0].toLowerCase(Locale.ENGLISH))
{
@@ -0,0 +0,0 @@ public class PaperCommand extends Command {
case "debug":
doDebug(sender, args);
break;
+ case "dumpwaiting":
+ ChunkTaskManager.dumpAllChunkLoadInfo();
+ break;
case "chunkinfo":
doChunkInfo(sender, args);
break;
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -1824,7 +1862,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import net.minecraft.server.IChunkAccess;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.NBTTagCompound;
+import net.minecraft.server.PlayerChunk;
+import net.minecraft.server.WorldServer;
+import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.Level;
+import org.bukkit.Bukkit;
+import org.spigotmc.AsyncCatcher;
@@ -1912,20 +1952,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // log current status of chunk to indicate whether we're waiting on generation or loading
+ net.minecraft.server.PlayerChunk chunkHolder = chunkInfo.world.getChunkProvider().playerChunkMap.getVisibleChunk(key);
+
+ if (chunkHolder == null) {
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - null");
+ } else {
+ IChunkAccess chunk = chunkHolder.getAvailableChunkNow();
+ net.minecraft.server.ChunkStatus holderStatus = chunkHolder.getChunkHolderStatus();
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - non-null");
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString()));
+ }
+
+ dumpChunkInfo(chunkHolder, chunkInfo.chunkX, chunkInfo.chunkZ);
+ }
+ }
+ }
+
+ static void dumpChunkInfo(PlayerChunk chunkHolder, int x, int z) {
+ dumpChunkInfo(chunkHolder, x, z, 0);
+ }
+ static void dumpChunkInfo(PlayerChunk chunkHolder, int x, int z, int indent) {
+ String indentStr = StringUtils.repeat(" ", indent);
+ if (chunkHolder == null) {
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - null for (" + x +"," + z +")");
+ } else {
+ IChunkAccess chunk = chunkHolder.getAvailableChunkNow();
+ net.minecraft.server.ChunkStatus holderStatus = chunkHolder.getChunkHolderStatus();
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder - non-null");
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Ticket Status - " + PlayerChunk.getChunkStatus(chunkHolder.getTicketLevel()));
+ PaperFileIOThread.LOGGER.log(Level.ERROR, indentStr + "Chunk Holder Status - " + ((holderStatus == null) ? "null" : holderStatus.toString()));
+ }
+ }
+
+ public static void initGlobalLoadThreads(int threads) {
+ if (threads <= 0 || globalWorkers != null) {
+ return;