Improve spawn loading and debug output for waiting on a chunk (#2595)

Spawn loading has been changed to use getChunkAt calls to manually
load chunks since watchdog can watch these calls and so we guard
against plugins/players changing the radius of a spawn while it's
loading

Debug output has been improved to note the status of the currently
waiting chunk
This commit is contained in:
Spottedleaf 2019-09-29 18:23:09 -07:00
parent fe0c5d9dc6
commit b0601574e0
3 changed files with 55 additions and 23 deletions

View File

@ -1901,7 +1901,7 @@ index 0000000000..1dfa8abfd8
+} +}
diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
new file mode 100644 new file mode 100644
index 0000000000..1d69715e26 index 0000000000..59d73bfad7
--- /dev/null --- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
@ -1992,12 +1992,24 @@ index 0000000000..1d69715e26
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk wait task info below: "); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk wait task info below: ");
+ +
+ for (final ChunkInfo chunkInfo : WAITING_CHUNKS) { + for (final ChunkInfo chunkInfo : WAITING_CHUNKS) {
+ final ChunkLoadTask loadTask = chunkInfo.world.asyncChunkTaskManager.chunkLoadTasks.get(IOUtil.getCoordinateKey(chunkInfo.chunkX, chunkInfo.chunkZ)); + final long key = IOUtil.getCoordinateKey(chunkInfo.chunkX, chunkInfo.chunkZ);
+ final ChunkSaveTask saveTask = chunkInfo.world.asyncChunkTaskManager.chunkSaveTasks.get(IOUtil.getCoordinateKey(chunkInfo.chunkX, chunkInfo.chunkZ)); + final ChunkLoadTask loadTask = chunkInfo.world.asyncChunkTaskManager.chunkLoadTasks.get(key);
+ final ChunkSaveTask saveTask = chunkInfo.world.asyncChunkTaskManager.chunkSaveTasks.get(key);
+ +
+ PaperFileIOThread.LOGGER.log(Level.ERROR, chunkInfo.chunkX + "," + chunkInfo.chunkZ + " in '" + chunkInfo.world.getWorld().getName() + ":"); + PaperFileIOThread.LOGGER.log(Level.ERROR, chunkInfo.chunkX + "," + chunkInfo.chunkZ + " in '" + chunkInfo.world.getWorld().getName() + ":");
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Load Task - " + (loadTask == null ? "none" : loadTask.toString())); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Load Task - " + (loadTask == null ? "none" : loadTask.toString()));
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Save Task - " + (saveTask == null ? "none" : saveTask.toString())); + PaperFileIOThread.LOGGER.log(Level.ERROR, "Save Task - " + (saveTask == null ? "none" : saveTask.toString()));
+ // 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();
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Holder - non-null");
+ PaperFileIOThread.LOGGER.log(Level.ERROR, "Chunk Status - " + ((chunk == null) ? "null chunk" : chunk.getChunkStatus().toString()));
+ }
+
+ } + }
+ } + }
+ } + }
@ -2897,7 +2909,7 @@ index 23d1935dd5..14f8b61042 100644
+ } + }
} }
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index ccf359dff1..a256f043ad 100644 index 5238a1a7ca..0b00581382 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -2947,7 +2959,7 @@ index af934ef8bc..34d0ab0d5e 100644
completablefuture = (CompletableFuture) this.statusFutures.get(i); completablefuture = (CompletableFuture) this.statusFutures.get(i);
if (completablefuture != null) { if (completablefuture != null) {
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
index fd0d2b6e67..9daf64bad4 100644 index fd0d2b6e67..31d106f951 100644
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java --- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -2977,6 +2989,15 @@ index fd0d2b6e67..9daf64bad4 100644
this.setViewDistance(i); this.setViewDistance(i);
} }
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
}
@Nullable
- protected PlayerChunk getVisibleChunk(long i) {
+ public PlayerChunk getVisibleChunk(long i) { // Paper - protected -> public
return (PlayerChunk) this.visibleChunks.get(i);
}
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override @Override
public void close() throws IOException { public void close() throws IOException {

View File

@ -6,7 +6,7 @@ Subject: [PATCH] Configurable Keep Spawn Loaded range per world
This lets you disable it for some worlds and lower it for others. This lets you disable it for some worlds and lower it for others.
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index d8bb13693..de11a91af 100644 index d8bb13693d..de11a91af6 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
@ -21,7 +21,7 @@ index d8bb13693..de11a91af 100644
+ } + }
} }
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index c70ab3caf..c58f6f50d 100644 index ee02001700..a6f112bd0f 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -30,9 +30,10 @@ index c70ab3caf..c58f6f50d 100644
+ // Paper start - configurable spawn reason + // Paper start - configurable spawn reason
+ int radiusBlocks = worldserver.paperConfig.keepLoadedRange; + int radiusBlocks = worldserver.paperConfig.keepLoadedRange;
+ worldloadlistener.setChunkRadius(radiusBlocks / 16); + int radiusChunks = radiusBlocks / 16 + ((radiusBlocks & 15) != 0 ? 1 : 0);
+ int totalChunks = ((radiusBlocks / 16) * 2 + 1); + int totalChunks = ((radiusChunks) * 2 + 1);
+ totalChunks *= totalChunks; + totalChunks *= totalChunks;
+ worldloadlistener.setChunkRadius(radiusBlocks / 16);
+ // Paper end + // Paper end
+ +
MinecraftServer.LOGGER.info("Preparing start region for dimension '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager().getType())); // CraftBukkit MinecraftServer.LOGGER.info("Preparing start region for dimension '{}'/{}", worldserver.getWorldData().getName(), DimensionManager.a(worldserver.worldProvider.getDimensionManager().getType())); // CraftBukkit
@ -43,25 +44,35 @@ index c70ab3caf..c58f6f50d 100644
chunkproviderserver.getLightEngine().a(500); chunkproviderserver.getLightEngine().a(500);
this.nextTick = SystemUtils.getMonotonicMillis(); this.nextTick = SystemUtils.getMonotonicMillis();
- chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(blockposition), 11, Unit.INSTANCE); - chunkproviderserver.addTicket(TicketType.START, new ChunkCoordIntPair(blockposition), 11, Unit.INSTANCE);
-
- while (chunkproviderserver.b() != 441) {
- // CraftBukkit start
- // this.nextTick = SystemUtils.getMonotonicMillis() + 10L;
- this.executeModerately();
- // CraftBukkit end
+ // Paper start - Configurable spawn radius + // Paper start - Configurable spawn radius
+ if (worldserver.keepSpawnInMemory) { + if (worldserver.keepSpawnInMemory) {
+ worldserver.addTicketsForSpawn(radiusBlocks, blockposition); + worldserver.addTicketsForSpawn(radiusBlocks, blockposition);
+ } +
+ // we use a getChunk loop since we don't need to worry about what some plugin does to keepSpawnInMemory
- while (chunkproviderserver.b() != 441) { + // or the spawn radius while we are loading
+ while (worldserver.keepSpawnInMemory && chunkproviderserver.b() != totalChunks) { + // just keep in mind too that executeModerately will handle player network queue (i.e commands)
+ // Paper end + int centerX = blockposition.getX() >> 4;
// CraftBukkit start + int centerZ = blockposition.getZ() >> 4;
// this.nextTick = SystemUtils.getMonotonicMillis() + 10L; + radiusChunks += 2; // we need to load radius +2 to get the chunks in ticking level
this.executeModerately(); + for (int xoff = -radiusChunks; xoff <= radiusChunks; ++xoff) {
// CraftBukkit end + for (int zoff = -radiusChunks; zoff <= radiusChunks; ++zoff) {
+ worldserver.getChunkAt(centerX + xoff, centerZ + zoff);
+ }
+ }
} }
+ // Paper end
+ LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorldData().getName()); // Paper + LOGGER.info("Loaded " + chunkproviderserver.b() + " spawn chunks for world " + worldserver.getWorldData().getName()); // Paper
// CraftBukkit start // CraftBukkit start
// this.nextTick = SystemUtils.getMonotonicMillis() + 10L; // this.nextTick = SystemUtils.getMonotonicMillis() + 10L;
diff --git a/src/main/java/net/minecraft/server/WorldLoadListener.java b/src/main/java/net/minecraft/server/WorldLoadListener.java diff --git a/src/main/java/net/minecraft/server/WorldLoadListener.java b/src/main/java/net/minecraft/server/WorldLoadListener.java
index d6762d385..7b6f5b2da 100644 index d6762d3853..7b6f5b2da0 100644
--- a/src/main/java/net/minecraft/server/WorldLoadListener.java --- a/src/main/java/net/minecraft/server/WorldLoadListener.java
+++ b/src/main/java/net/minecraft/server/WorldLoadListener.java +++ b/src/main/java/net/minecraft/server/WorldLoadListener.java
@@ -0,0 +0,0 @@ public interface WorldLoadListener { @@ -0,0 +0,0 @@ public interface WorldLoadListener {
@ -72,7 +83,7 @@ index d6762d385..7b6f5b2da 100644
+ void setChunkRadius(int radius); // Paper - allow changing chunk radius + void setChunkRadius(int radius); // Paper - allow changing chunk radius
} }
diff --git a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java diff --git a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java
index 3868572ae..ae77805f7 100644 index 3868572aed..ae77805f71 100644
--- a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java --- a/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java
+++ b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java +++ b/src/main/java/net/minecraft/server/WorldLoadListenerLogger.java
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger; @@ -0,0 +0,0 @@ import org.apache.logging.log4j.Logger;
@ -103,7 +114,7 @@ index 3868572ae..ae77805f7 100644
@Override @Override
public void a(ChunkCoordIntPair chunkcoordintpair) { public void a(ChunkCoordIntPair chunkcoordintpair) {
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
index 0f8f54d8e..8a3124fed 100644 index 0f8f54d8e9..8a3124fed4 100644
--- a/src/main/java/net/minecraft/server/WorldServer.java --- a/src/main/java/net/minecraft/server/WorldServer.java
+++ b/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java
@@ -0,0 +0,0 @@ public class WorldServer extends World { @@ -0,0 +0,0 @@ public class WorldServer extends World {
@ -196,7 +207,7 @@ index 0f8f54d8e..8a3124fed 100644
public LongSet getForceLoadedChunks() { public LongSet getForceLoadedChunks() {
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 38939ce81..0c31c349a 100644 index 38939ce81e..0c31c349ab 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World { @@ -0,0 +0,0 @@ public class CraftWorld implements World {

View File

@ -62,7 +62,7 @@ index 02dfd91c5e..8689e0f9f0 100644
public void close() throws IOException { public void close() throws IOException {
// CraftBukkit start // CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 098b3e5355..7e49d21625 100644 index a6f112bd0f..5238a1a7ca 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas