Slow down Forge chunk gen worker when save queue is to high.

Prevents task from completing while tons of chunks are pending save.
And add minimum notification every 60 seconds.
This commit is contained in:
LexManos committed 2018-04-03 15:26:28 -07:00
1 parent 501e030f3e
commit 34706c7cd7
3 files changed
+58 -19

No files matched your search

+5 -5
View File
@@ -1,10 +1,10 @@
{
"assetIndex": {
"id": "1.12",
"sha1": "98c430c16a705f18a58a281b27caabf3ef09d40d",
"size": 169253,
"url": "https://launchermeta.mojang.com/mc/assets/1.12/98c430c16a705f18a58a281b27caabf3ef09d40d/1.12.json",
"totalSize": 127453671
"sha1": "e75e9535754c6f2158b0b18b35660f45c4495d78",
"size": 169257,
"url": "https://launchermeta.mojang.com/mc/assets/1.12/e75e9535754c6f2158b0b18b35660f45c4495d78/1.12.json",
"totalSize": 127722338
},
"assets": "1.12",
"downloads": {
@@ -719,6 +719,6 @@
"minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}",
"minimumLauncherVersion": 18,
"releaseTime": "2017-09-18T08:39:46+00:00",
"time": "2018-02-15T16:26:45+00:00",
"time": "2018-04-02T07:39:26+00:00",
"type": "release"
}
@@ -179,3 +179,13 @@
}
@Nullable
@@ -563,4 +650,9 @@
return entity;
}
}
+
+ public int getPendingSaveCount()
+ {
+ return this.field_75828_a.size();
+ }
}
@@ -18,6 +18,7 @@
*/
package net.minecraftforge.server.command;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Queue;
@@ -26,8 +27,10 @@ import net.minecraft.server.management.PlayerChunkMapEntry;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentBase;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.MinecraftException;
import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.AnvilChunkLoader;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.WorldWorkerManager.IWorker;
@@ -40,6 +43,7 @@ public class ChunkGenWorker implements IWorker
private final Queue<BlockPos> queue;
private final int notificationFrequency;
private int lastNotification = 0;
private long lastNotifcationTime = 0;
private int genned = 0;
private Boolean keepingLoaded;
@@ -51,6 +55,7 @@ public class ChunkGenWorker implements IWorker
this.dim = dim;
this.queue = buildQueue();
this.notificationFrequency = interval != -1 ? interval : Math.max(total / 20, 100); //Every 5% or every 100, whichever is more.
this.lastNotifcationTime = System.currentTimeMillis(); //We also notify at least once every 60 seconds, to show we haven't froze.
}
protected Queue<BlockPos> buildQueue()
@@ -97,34 +102,48 @@ public class ChunkGenWorker implements IWorker
}
@Override
public void work()
public boolean doWork()
{
WorldServer world = DimensionManager.getWorld(dim);
if (world == null)
{
DimensionManager.initDimension(dim);
world = DimensionManager.getWorld(dim);
if (world == null)
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.dim_fail", dim));
queue.clear();
return false;
}
}
AnvilChunkLoader loader = world.getChunkProvider().chunkLoader instanceof AnvilChunkLoader ? (AnvilChunkLoader)world.getChunkProvider().chunkLoader : null;
if (loader != null && loader.getPendingSaveCount() > 100)
{
if (lastNotifcationTime < System.currentTimeMillis() - 10*1000)
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.progress", total - queue.size(), total));
lastNotifcationTime = System.currentTimeMillis();
}
return false;
}
BlockPos next = queue.poll();
if (next != null)
{
WorldServer world = DimensionManager.getWorld(dim);
if (world == null)
{
DimensionManager.initDimension(dim);
world = DimensionManager.getWorld(dim);
if (world == null)
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.dim_fail", dim));
queue.clear();
return;
}
}
// While we work we don't want to cause world load spam so pause unloading the world.
if (keepingLoaded == null)
{
keepingLoaded = DimensionManager.keepDimensionLoaded(dim, true);
}
if (++lastNotification >= notificationFrequency)
if (++lastNotification >= notificationFrequency || lastNotifcationTime < System.currentTimeMillis() - 60*1000)
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.progress", total - queue.size(), total));
lastNotification = 0;
lastNotifcationTime = System.currentTimeMillis();
}
int x = next.getX();
@@ -144,6 +163,14 @@ public class ChunkGenWorker implements IWorker
world.getChunkFromChunkCoords(x + 1, z + 1),
world.getChunkFromChunkCoords(x, z + 1),
};
try
{
world.getChunkProvider().chunkLoader.saveChunk(world, target);
}
catch (IOException | MinecraftException e)
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.saveerror", e.getMessage()));
}
genned++;
}
@@ -162,6 +189,8 @@ public class ChunkGenWorker implements IWorker
{
DimensionManager.keepDimensionLoaded(dim, false);
}
return false;
}
return true;
}
}