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 committed by Zach
parent 826b4762c0
commit bfc807c27a
3 changed files with 64 additions and 32 deletions

View file

@ -1,4 +1,4 @@
From b4155a3581c39d61d4eab95e5a6103d77924fe37 Mon Sep 17 00:00:00 2001 From e33d861d00db79f27822b8fdb5dff1184282f8f6 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co> From: Aikar <aikar@aikar.co>
Date: Sat, 13 Sep 2014 23:14:43 -0400 Date: Sat, 13 Sep 2014 23:14:43 -0400
Subject: [PATCH] Configurable Keep Spawn Loaded range per world Subject: [PATCH] Configurable Keep Spawn Loaded range per world
@ -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
@@ -483,4 +483,10 @@ public class PaperWorldConfig { @@ -483,4 +483,10 @@ public class PaperWorldConfig {
@ -21,47 +21,58 @@ 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
@@ -577,6 +577,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -577,6 +577,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.forceTicks = true; this.forceTicks = true;
// CraftBukkit end // CraftBukkit end
+ // 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
BlockPosition blockposition = worldserver.getSpawn(); BlockPosition blockposition = worldserver.getSpawn();
@@ -585,14 +592,19 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -585,14 +593,24 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
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
@@ -9,4 +9,6 @@ public interface WorldLoadListener { @@ -9,4 +9,6 @@ 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
@@ -7,16 +7,24 @@ import org.apache.logging.log4j.Logger; @@ -7,16 +7,24 @@ 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
@@ -1525,13 +1525,85 @@ public class WorldServer extends World { @@ -1525,13 +1525,85 @@ 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
@@ -1853,15 +1853,21 @@ public class CraftWorld implements World { @@ -1853,15 +1853,21 @@ public class CraftWorld implements World {
@ -226,5 +237,5 @@ index 38939ce81..0c31c349a 100644
@Override @Override
-- --
2.23.0 2.22.1

View file

@ -1,4 +1,4 @@
From 2b993316234835b83c786522f6a71a120f030618 Mon Sep 17 00:00:00 2001 From 52ddb3aedd0e33aa0f7ea8aa8013cbdfa20031d2 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com> From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 9 Jun 2019 03:53:22 +0100 Date: Sun, 9 Jun 2019 03:53:22 +0100
Subject: [PATCH] incremental chunk saving Subject: [PATCH] incremental chunk saving
@ -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
@@ -165,6 +165,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -165,6 +165,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@ -73,7 +73,7 @@ index 098b3e5355..7e49d21625 100644
public File bukkitDataPackFolder; public File bukkitDataPackFolder;
public CommandDispatcher vanillaCommandDispatcher; public CommandDispatcher vanillaCommandDispatcher;
private boolean forceTicks; private boolean forceTicks;
@@ -1102,14 +1103,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -1108,14 +1109,28 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.serverPing.b().a(agameprofile); this.serverPing.b().a(agameprofile);
} }

View file

@ -1,4 +1,4 @@
From 9413728661866351fccf0d24d8c332f7e53c9ec1 Mon Sep 17 00:00:00 2001 From 25eb4ce4491f0ab4ed97614dc5de32690bd815fb Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com> From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 13 Jul 2019 09:23:10 -0700 Date: Sat, 13 Jul 2019 09:23:10 -0700
Subject: [PATCH] Asynchronous chunk IO and loading Subject: [PATCH] Asynchronous chunk IO and loading
@ -1901,10 +1901,10 @@ 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 +1,441 @@ @@ -0,0 +1,453 @@
+package com.destroystokyo.paper.io.chunk; +package com.destroystokyo.paper.io.chunk;
+ +
+import com.destroystokyo.paper.io.PaperFileIOThread; +import com.destroystokyo.paper.io.PaperFileIOThread;
@ -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,10 +2909,10 @@ 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
@@ -774,6 +774,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -780,6 +780,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.getUserCache().c(false); // Paper this.getUserCache().c(false); // Paper
} }
// Spigot end // Spigot end
@ -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
@@ -62,7 +62,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -62,7 +62,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@ -2977,6 +2989,15 @@ index fd0d2b6e67..9daf64bad4 100644
this.setViewDistance(i); this.setViewDistance(i);
} }
@@ -180,7 +180,7 @@ 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);
}
@@ -293,6 +293,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { @@ -293,6 +293,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
@Override @Override
public void close() throws IOException { public void close() throws IOException {