mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-25 12:05:53 +01:00
d1a72eac31
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 1fc1020a PR-1049: Add MenuType API 8ae2e3be PR-1055: Expand riptiding API cac68bfb SPIGOT-7890: AttributeModifier#getUniqueId() doesn't match the UUID passed to its constructor 7004fcf2 SPIGOT-7886: Fix mistake in AttributeModifier UUID shim 1ac7f950 PR-1054: Add FireworkMeta#hasPower 4cfb565f SPIGOT-7873: Add powered state for skulls CraftBukkit Changes: bbb30e7a8 SPIGOT-7894: NPE when sending tile entity update ba21e9472 SPIGOT-7895: PlayerItemBreakEvent not firing 0fb24bbe0 SPIGOT-7875: Fix PlayerItemConsumeEvent cancellation causing client-side desync 815066449 SPIGOT-7891: Can't remove second ingredient of MerchantRecipe 45c206f2c PR-1458: Add MenuType API 19c8ef9ae SPIGOT-7867: Merchant instanceof AbstractVillager always returns false 4e006d28f PR-1468: Expand riptiding API bd8aded7d Ignore checks in CraftPlayerProfile for ResolvableProfile used in profile components 8679620b5 SPIGOT-7889: Fix tool component deserialisation without speed and/or correct-for-drops 8d5222691 SPIGOT-7882, PR-1467: Fix conversion of name in Profile Component to empty if it is missing 63f91669a SPIGOT-7887: Remove duplicate ProjectileHitEvent for fireballs 7070de8c8 SPIGOT-7878: Server#getLootTable does not return null on invalid loot table 060ee6cae SPIGOT-7876: Can't kick player or disconnect player in PlayerLoginEvent when checking for cookies 7ccb86cc0 PR-1465: Add FireworkMeta#hasPower 804ad6491 SPIGOT-7873: Add powered state for skulls f9610cdcb Improve minecart movement Spigot Changes: a759b629 Rebuild patches Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
165 lines
8.5 KiB
Diff
165 lines
8.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Cryptite <cryptite@gmail.com>
|
|
Date: Tue, 27 Jun 2023 11:35:52 -0500
|
|
Subject: [PATCH] Write SavedData IO async
|
|
|
|
Co-Authored-By: Shane Freeder <theboyetronic@gmail.com>
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
index 4a5dc7fd4eb1a7ab1ec371f0f107de882f88149c..dcb5651d1d9b10b40430fb2f713beedf68336704 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
|
@@ -369,6 +369,13 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon
|
|
|
|
public void close(boolean save) throws IOException {
|
|
((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.level).moonrise$getChunkTaskScheduler().chunkHolderManager.close(save, true); // Paper - rewrite chunk system
|
|
+ // Paper start - Write SavedData IO async
|
|
+ try {
|
|
+ this.dataStorage.close();
|
|
+ } catch (final IOException e) {
|
|
+ LOGGER.error("Failed to close persistent world data", e);
|
|
+ }
|
|
+ // Paper end - Write SavedData IO async
|
|
}
|
|
|
|
// CraftBukkit start - modelled on below
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
index c5698b05cc3ea4cb1bc6789c30f2aab76748d491..2931e1dd0c8ae5ac1c9ec42f90dd5ab57595bf60 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1330,7 +1330,7 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
|
|
progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
|
|
}
|
|
|
|
- this.saveLevelData();
|
|
+ this.saveLevelData(!close); // Paper - Write SavedData IO async
|
|
if (progressListener != null) {
|
|
progressListener.progressStage(Component.translatable("menu.savingChunks"));
|
|
}
|
|
@@ -1361,12 +1361,12 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
|
|
// CraftBukkit end
|
|
}
|
|
|
|
- private void saveLevelData() {
|
|
+ private void saveLevelData(boolean async) { // Paper - Write SavedData IO async
|
|
if (this.dragonFight != null) {
|
|
this.serverLevelData.setEndDragonFightData(this.dragonFight.saveData()); // CraftBukkit
|
|
}
|
|
|
|
- this.getChunkSource().getDataStorage().save();
|
|
+ this.getChunkSource().getDataStorage().save(async); // Paper - Write SavedData IO async
|
|
}
|
|
|
|
public <T extends Entity> List<? extends T> getEntities(EntityTypeTest<Entity, T> filter, Predicate<? super T> predicate) {
|
|
diff --git a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
|
index 0382b6597a130d746f8954a93a756a9d1ac81d50..cb39c629af1827078f35904a373d35a63fea17ff 100644
|
|
--- a/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
|
+++ b/src/main/java/net/minecraft/util/worldupdate/WorldUpgrader.java
|
|
@@ -116,7 +116,13 @@ public class WorldUpgrader {
|
|
(new WorldUpgrader.PoiUpgrader(this)).upgrade();
|
|
WorldUpgrader.LOGGER.info("Upgrading blocks");
|
|
(new WorldUpgrader.ChunkUpgrader()).upgrade();
|
|
- this.overworldDataStorage.save();
|
|
+ // Paper start - Write SavedData IO async
|
|
+ try {
|
|
+ this.overworldDataStorage.close();
|
|
+ } catch (final IOException e) {
|
|
+ LOGGER.error("Failed to close persistent world data", e);
|
|
+ }
|
|
+ // Paper end - Write SavedData IO async
|
|
i = Util.getMillis() - i;
|
|
WorldUpgrader.LOGGER.info("World optimizaton finished after {} seconds", i / 1000L);
|
|
this.finished = true;
|
|
diff --git a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java
|
|
index 9cc3850bb70dfbcf342651360314a19fd9ea3ecc..4cbb943b702baaeb8bfd2b558cc848e719cf095d 100644
|
|
--- a/src/main/java/net/minecraft/world/level/saveddata/SavedData.java
|
|
+++ b/src/main/java/net/minecraft/world/level/saveddata/SavedData.java
|
|
@@ -30,20 +30,36 @@ public abstract class SavedData {
|
|
return this.dirty;
|
|
}
|
|
|
|
+ // Paper start - Write SavedData IO async - joining is evil, but we assume the old blocking behavior here just for safety
|
|
+ @io.papermc.paper.annotation.DoNotUse
|
|
public void save(File file, HolderLookup.Provider registryLookup) {
|
|
+ save(file, registryLookup, null).join();
|
|
+ }
|
|
+
|
|
+ public java.util.concurrent.CompletableFuture<Void> save(File file, HolderLookup.Provider registryLookup, @org.jetbrains.annotations.Nullable java.util.concurrent.ExecutorService ioExecutor) {
|
|
+ // Paper end - Write SavedData IO async
|
|
if (this.isDirty()) {
|
|
CompoundTag compoundTag = new CompoundTag();
|
|
compoundTag.put("data", this.save(new CompoundTag(), registryLookup));
|
|
NbtUtils.addCurrentDataVersion(compoundTag);
|
|
|
|
+ Runnable writeRunnable = () -> { // Paper - Write SavedData IO async
|
|
try {
|
|
NbtIo.writeCompressed(compoundTag, file.toPath());
|
|
} catch (IOException var5) {
|
|
LOGGER.error("Could not save data {}", this, var5);
|
|
}
|
|
+ }; // Paper - Write SavedData IO async
|
|
|
|
this.setDirty(false);
|
|
+ // Paper start - Write SavedData IO async
|
|
+ if (ioExecutor == null) {
|
|
+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable); // No executor, just use common pool
|
|
+ }
|
|
+ return java.util.concurrent.CompletableFuture.runAsync(writeRunnable, ioExecutor);
|
|
}
|
|
+ return java.util.concurrent.CompletableFuture.completedFuture(null);
|
|
+ // Paper end - Write SavedData IO async
|
|
}
|
|
|
|
public static record Factory<T extends SavedData>(
|
|
diff --git a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
|
|
index 7d98d2911e9d6ec429ce7df1f1f2650c7ea32325..6e23e69abd56eeda3b52a22019e1b74ae10682e7 100644
|
|
--- a/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
|
|
+++ b/src/main/java/net/minecraft/world/level/storage/DimensionDataStorage.java
|
|
@@ -23,17 +23,19 @@ import net.minecraft.util.datafix.DataFixTypes;
|
|
import net.minecraft.world.level.saveddata.SavedData;
|
|
import org.slf4j.Logger;
|
|
|
|
-public class DimensionDataStorage {
|
|
+public class DimensionDataStorage implements java.io.Closeable { // Paper - Write SavedData IO async
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
public final Map<String, SavedData> cache = Maps.newHashMap();
|
|
private final DataFixer fixerUpper;
|
|
private final HolderLookup.Provider registries;
|
|
private final File dataFolder;
|
|
+ protected final java.util.concurrent.ExecutorService ioExecutor; // Paper - Write SavedData IO async
|
|
|
|
public DimensionDataStorage(File directory, DataFixer dataFixer, HolderLookup.Provider registryLookup) {
|
|
this.fixerUpper = dataFixer;
|
|
this.dataFolder = directory;
|
|
this.registries = registryLookup;
|
|
+ this.ioExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("DimensionDataIO - " + dataFolder.getParent() + " - %d").setDaemon(true).build()); // Paper - Write SavedData IO async
|
|
}
|
|
|
|
private File getDataFile(String id) {
|
|
@@ -123,10 +125,23 @@ public class DimensionDataStorage {
|
|
return bl;
|
|
}
|
|
|
|
- public void save() {
|
|
+ // Paper start - Write SavedData IO async
|
|
+ @Override
|
|
+ public void close() throws IOException {
|
|
+ save(false);
|
|
+ this.ioExecutor.shutdown();
|
|
+ }
|
|
+ // Paper end - Write SavedData IO async
|
|
+
|
|
+ public void save(boolean async) { // Paper - Write SavedData IO async
|
|
this.cache.forEach((id, state) -> {
|
|
if (state != null) {
|
|
- state.save(this.getDataFile(id), this.registries);
|
|
+ // Paper start - Write SavedData IO async
|
|
+ final java.util.concurrent.CompletableFuture<Void> save = state.save(this.getDataFile(id), this.registries, this.ioExecutor);
|
|
+ if (!async) {
|
|
+ save.join();
|
|
+ }
|
|
+ // Paper end - Write SavedData IO async
|
|
}
|
|
});
|
|
}
|