From 9e1620e3d385eebcb59617c9a4462982c8857086 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sun, 15 Sep 2019 20:39:30 -0700 Subject: [PATCH] Improve save logic (#2485) Only wait for IO at the end of the save we also were not force flushing async saves with /save-all flush --- ...10-Asynchronous-chunk-IO-and-loading.patch | 106 +++++++++++------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/Spigot-Server-Patches/0410-Asynchronous-chunk-IO-and-loading.patch b/Spigot-Server-Patches/0410-Asynchronous-chunk-IO-and-loading.patch index 55d615f89..8e5b3ac13 100644 --- a/Spigot-Server-Patches/0410-Asynchronous-chunk-IO-and-loading.patch +++ b/Spigot-Server-Patches/0410-Asynchronous-chunk-IO-and-loading.patch @@ -1,4 +1,4 @@ -From 5fe2bc63a46c55a1a7ba4e3b6bc81978252e7ccc Mon Sep 17 00:00:00 2001 +From 78fb1395fde968993c5cc8d1f76ed4989fde3b7f Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Sat, 13 Jul 2019 09:23:10 -0700 Subject: [PATCH] Asynchronous chunk IO and loading @@ -121,7 +121,7 @@ tasks required to be executed by the chunk load task (i.e lighting and some poi tasks). diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java -index 92c32c48d2..f4d5db02f7 100644 +index 92c32c48d..f4d5db02f 100644 --- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java +++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java @@ -58,6 +58,17 @@ public class WorldTimingsHandler { @@ -161,7 +161,7 @@ index 92c32c48d2..f4d5db02f7 100644 public static Timing getTickList(WorldServer worldserver, String timingsType) { diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java -index 5942c3438e..61eeb6747a 100644 +index 5942c3438..61eeb6747 100644 --- a/src/main/java/com/destroystokyo/paper/PaperConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java @@ -1,5 +1,6 @@ @@ -237,7 +237,7 @@ index 5942c3438e..61eeb6747a 100644 + } } diff --git a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java -index 23626bef3a..1edcecd2ee 100644 +index 23626bef3..1edcecd2e 100644 --- a/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java +++ b/src/main/java/com/destroystokyo/paper/antixray/ChunkPacketBlockControllerAntiXray.java @@ -9,6 +9,7 @@ import java.util.concurrent.Executors; @@ -318,7 +318,7 @@ index 23626bef3a..1edcecd2ee 100644 diff --git a/src/main/java/com/destroystokyo/paper/io/IOUtil.java b/src/main/java/com/destroystokyo/paper/io/IOUtil.java new file mode 100644 -index 0000000000..5af0ac3d9e +index 000000000..5af0ac3d9 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/IOUtil.java @@ -0,0 +1,62 @@ @@ -386,7 +386,7 @@ index 0000000000..5af0ac3d9e +} diff --git a/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java new file mode 100644 -index 0000000000..4f10a8311e +index 000000000..4f10a8311 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PaperFileIOThread.java @@ -0,0 +1,661 @@ @@ -1053,7 +1053,7 @@ index 0000000000..4f10a8311e +} diff --git a/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java new file mode 100644 -index 0000000000..c3ca3c4a1c +index 000000000..c3ca3c4a1 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/PrioritizedTaskQueue.java @@ -0,0 +1,258 @@ @@ -1317,7 +1317,7 @@ index 0000000000..c3ca3c4a1c +} diff --git a/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java new file mode 100644 -index 0000000000..f127ef236e +index 000000000..f127ef236 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/QueueExecutorThread.java @@ -0,0 +1,244 @@ @@ -1567,7 +1567,7 @@ index 0000000000..f127ef236e +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java new file mode 100644 -index 0000000000..305da47868 +index 000000000..305da4786 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkLoadTask.java @@ -0,0 +1,149 @@ @@ -1722,7 +1722,7 @@ index 0000000000..305da47868 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java new file mode 100644 -index 0000000000..60312b85f9 +index 000000000..60312b85f --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkSaveTask.java @@ -0,0 +1,112 @@ @@ -1840,7 +1840,7 @@ index 0000000000..60312b85f9 +} diff --git a/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java new file mode 100644 -index 0000000000..1dfa8abfd8 +index 000000000..1dfa8abfd --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTask.java @@ -0,0 +1,40 @@ @@ -1886,7 +1886,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 new file mode 100644 -index 0000000000..b1b48a6f49 +index 000000000..b1b48a6f4 --- /dev/null +++ b/src/main/java/com/destroystokyo/paper/io/chunk/ChunkTaskManager.java @@ -0,0 +1,438 @@ @@ -2329,7 +2329,7 @@ index 0000000000..b1b48a6f49 + +} diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java -index e0bd03b3be..f793ba08e7 100644 +index e0bd03b3b..f793ba08e 100644 --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java @@ -124,11 +124,137 @@ public class ChunkProviderServer extends IChunkProvider { @@ -2499,7 +2499,7 @@ index e0bd03b3be..f793ba08e7 100644 } finally { playerChunkMap.callbackExecutor.run(); diff --git a/src/main/java/net/minecraft/server/ChunkRegionLoader.java b/src/main/java/net/minecraft/server/ChunkRegionLoader.java -index a028074112..98cc4efcf5 100644 +index a02807411..98cc4efcf 100644 --- a/src/main/java/net/minecraft/server/ChunkRegionLoader.java +++ b/src/main/java/net/minecraft/server/ChunkRegionLoader.java @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -2768,7 +2768,7 @@ index a028074112..98cc4efcf5 100644 nbttagcompound1.set("PostProcessing", a(ichunkaccess.l())); diff --git a/src/main/java/net/minecraft/server/ChunkStatus.java b/src/main/java/net/minecraft/server/ChunkStatus.java -index e324989b46..abb0d69d2f 100644 +index e324989b4..abb0d69d2 100644 --- a/src/main/java/net/minecraft/server/ChunkStatus.java +++ b/src/main/java/net/minecraft/server/ChunkStatus.java @@ -153,6 +153,7 @@ public class ChunkStatus { @@ -2780,7 +2780,7 @@ index e324989b46..abb0d69d2f 100644 return ChunkStatus.r.getInt(chunkstatus.c()); } diff --git a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java -index d521d25cf5..84024e6ba4 100644 +index d521d25cf..84024e6ba 100644 --- a/src/main/java/net/minecraft/server/IAsyncTaskHandler.java +++ b/src/main/java/net/minecraft/server/IAsyncTaskHandler.java @@ -91,7 +91,7 @@ public abstract class IAsyncTaskHandler implements Mailbox { + return ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk; +- }).filter(this::saveChunk).forEach((ichunkaccess) -> { ++ }).filter((chunk) -> this.saveChunk(chunk, true)).forEach((ichunkaccess) -> { // Paper - async io for chunk save + mutableboolean.setTrue(); + }); + } while (mutableboolean.isTrue()); +@@ -353,17 +354,19 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { + this.b(() -> { + return true; + }); ++ this.world.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour + PlayerChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.x.getName()); + } else { + this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).forEach((playerchunk) -> { + IChunkAccess ichunkaccess = (IChunkAccess) playerchunk.getChunkSave().getNow(null); // CraftBukkit - decompile error + + if (ichunkaccess instanceof ProtoChunkExtension || ichunkaccess instanceof Chunk) { +- this.saveChunk(ichunkaccess); ++ this.saveChunk(ichunkaccess, true); // Paper + playerchunk.m(); } }); @@ -2984,7 +3006,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 } } -@@ -373,11 +375,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -373,11 +376,15 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { protected void unloadChunks(BooleanSupplier booleansupplier) { GameProfilerFiller gameprofilerfiller = this.world.getMethodProfiler(); @@ -3000,7 +3022,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 } gameprofilerfiller.exit(); -@@ -418,6 +424,60 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -418,6 +425,60 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -3061,7 +3083,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 private void a(long i, PlayerChunk playerchunk) { CompletableFuture completablefuture = playerchunk.getChunkSave(); Consumer consumer = (ichunkaccess) -> { // CraftBukkit - decompile error -@@ -431,13 +491,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -431,13 +492,20 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { ((Chunk) ichunkaccess).setLoaded(false); } @@ -3083,7 +3105,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 this.lightEngine.a(ichunkaccess.getPos()); this.lightEngine.queueUpdate(); this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null); -@@ -507,26 +574,30 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -507,26 +575,30 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } @@ -3130,7 +3152,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 } catch (ReportedException reportedexception) { Throwable throwable = reportedexception.getCause(); -@@ -540,7 +611,27 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -540,7 +612,27 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray @@ -3159,7 +3181,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 } private CompletableFuture> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) { -@@ -746,18 +837,43 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -746,18 +838,43 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { return this.v.get(); } @@ -3211,7 +3233,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 ichunkaccess.setLastSaved(this.world.getTime()); ichunkaccess.setNeedsSaving(false); -@@ -768,27 +884,33 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -768,27 +885,33 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { NBTTagCompound nbttagcompound; if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) { @@ -3248,7 +3270,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 } protected void setViewDistance(int i) { -@@ -892,6 +1014,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -892,6 +1015,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } } @@ -3291,7 +3313,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 @Nullable public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public NBTTagCompound nbttagcompound = this.read(chunkcoordintpair); -@@ -914,12 +1072,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -914,12 +1073,42 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { // Paper start - chunk status cache "api" public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) { @@ -3334,7 +3356,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 RegionFile regionFile = this.getRegionFile(chunkPos, false); if (!regionFile.chunkExists(chunkPos)) { -@@ -931,18 +1119,56 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -931,18 +1120,56 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { if (status != null) { return status; } @@ -3393,7 +3415,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 public IChunkAccess getUnloadingChunk(int chunkX, int chunkZ) { PlayerChunk chunkHolder = this.pendingUnload.get(ChunkCoordIntPair.pair(chunkX, chunkZ)); return chunkHolder == null ? null : chunkHolder.getAvailableChunkNow(); -@@ -1290,6 +1516,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { +@@ -1290,6 +1517,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d { } @@ -3402,7 +3424,7 @@ index fd0d2b6e67..e6b7c41bf0 100644 return this.n; } diff --git a/src/main/java/net/minecraft/server/RegionFile.java b/src/main/java/net/minecraft/server/RegionFile.java -index a8c8ace46c..22144eb002 100644 +index a8c8ace46..22144eb00 100644 --- a/src/main/java/net/minecraft/server/RegionFile.java +++ b/src/main/java/net/minecraft/server/RegionFile.java @@ -343,7 +343,7 @@ public class RegionFile implements AutoCloseable { @@ -3415,7 +3437,7 @@ index a8c8ace46c..22144eb002 100644 this.b.close(); } diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java -index d2b3289450..d3d6107422 100644 +index d2b328945..d3d610742 100644 --- a/src/main/java/net/minecraft/server/RegionFileCache.java +++ b/src/main/java/net/minecraft/server/RegionFileCache.java @@ -48,13 +48,13 @@ public abstract class RegionFileCache implements AutoCloseable { @@ -3444,7 +3466,7 @@ index d2b3289450..d3d6107422 100644 RegionFile regionfile = a(pos, true); diff --git a/src/main/java/net/minecraft/server/RegionFileSection.java b/src/main/java/net/minecraft/server/RegionFileSection.java -index 4b3e0c0f01..04b7dab646 100644 +index 4b3e0c0f0..04b7dab64 100644 --- a/src/main/java/net/minecraft/server/RegionFileSection.java +++ b/src/main/java/net/minecraft/server/RegionFileSection.java @@ -24,7 +24,7 @@ public class RegionFileSection extends RegionFi @@ -3546,7 +3568,7 @@ index 4b3e0c0f01..04b7dab646 100644 + // Paper end } diff --git a/src/main/java/net/minecraft/server/TicketType.java b/src/main/java/net/minecraft/server/TicketType.java -index 9c114d2d37..e3150f85a5 100644 +index 9c114d2d3..e3150f85a 100644 --- a/src/main/java/net/minecraft/server/TicketType.java +++ b/src/main/java/net/minecraft/server/TicketType.java @@ -22,6 +22,7 @@ public class TicketType { @@ -3558,7 +3580,7 @@ index 9c114d2d37..e3150f85a5 100644 public static TicketType a(String s, Comparator comparator) { return new TicketType<>(s, comparator, 0L); diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java -index 3169590641..0e98b7803b 100644 +index 316959064..0e98b7803 100644 --- a/src/main/java/net/minecraft/server/VillagePlace.java +++ b/src/main/java/net/minecraft/server/VillagePlace.java @@ -20,8 +20,16 @@ public class VillagePlace extends RegionFileSection { @@ -3647,7 +3669,7 @@ index 3169590641..0e98b7803b 100644 HAS_SPACE(VillagePlaceRecord::d), IS_OCCUPIED(VillagePlaceRecord::e), ANY((villageplacerecord) -> { diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java -index f1ad7be754..0c1f4e6e1e 100644 +index f1ad7be75..0c1f4e6e1 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -78,6 +78,79 @@ public class WorldServer extends World { @@ -3740,7 +3762,7 @@ index f1ad7be754..0c1f4e6e1e 100644 public void doTick(BooleanSupplier booleansupplier) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java -index 088f0800f2..5e552029ac 100644 +index 088f0800f..5e552029a 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -553,22 +553,23 @@ public class CraftWorld implements World { @@ -3802,7 +3824,7 @@ index 088f0800f2..5e552029ac 100644 @Override public int getViewDistance() { diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java -index a1d93200e6..6ca0ebfdee 100644 +index a1d93200e..6ca0ebfde 100644 --- a/src/main/java/org/spigotmc/WatchdogThread.java +++ b/src/main/java/org/spigotmc/WatchdogThread.java @@ -6,6 +6,7 @@ import java.lang.management.ThreadInfo;