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 2018-04-03 15:26:28 -07:00
parent 501e030f3e
commit 34706c7cd7
3 changed files with 58 additions and 19 deletions

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"
}

View file

@ -179,3 +179,13 @@
}
@Nullable
@@ -563,4 +650,9 @@
return entity;
}
}
+
+ public int getPendingSaveCount()
+ {
+ return this.field_75828_a.size();
+ }
}

View file

@ -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,11 +102,7 @@ public class ChunkGenWorker implements IWorker
}
@Override
public void work()
{
BlockPos next = queue.poll();
if (next != null)
public boolean doWork()
{
WorldServer world = DimensionManager.getWorld(dim);
if (world == null)
@ -112,19 +113,37 @@ public class ChunkGenWorker implements IWorker
{
listener.sendMessage(TextComponentHelper.createComponentTranslation(listener, "commands.forge.gen.dim_fail", dim));
queue.clear();
return;
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)
{
// 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;
}
}