mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-02-16 02:20:44 +00:00
improve mantle cleanup to prevent thread starvation
This commit is contained in:
@@ -23,6 +23,7 @@ import com.volmit.iris.core.IrisSettings;
|
||||
import com.volmit.iris.core.link.Identifier;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||
import com.volmit.iris.engine.data.cache.Cache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedWorldManager;
|
||||
import com.volmit.iris.engine.object.*;
|
||||
@@ -57,13 +58,10 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -81,6 +79,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
private final ChronoLatch cln;
|
||||
private final ChronoLatch chunkUpdater;
|
||||
private final ChronoLatch chunkDiscovery;
|
||||
private final KMap<Long, Future<?>> cleanup = new KMap<>();
|
||||
private final ScheduledExecutorService cleanupService;
|
||||
private double energy = 25;
|
||||
private int entityCount = 0;
|
||||
private long charge = 0;
|
||||
@@ -98,6 +98,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
looper = null;
|
||||
chunkUpdater = null;
|
||||
chunkDiscovery = null;
|
||||
cleanupService = null;
|
||||
id = -1;
|
||||
}
|
||||
|
||||
@@ -109,6 +110,11 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
cl = new ChronoLatch(3000);
|
||||
ecl = new ChronoLatch(250);
|
||||
clw = new ChronoLatch(1000, true);
|
||||
cleanupService = Executors.newSingleThreadScheduledExecutor(runnable -> {
|
||||
var thread = new Thread(runnable, "Iris Mantle Cleanup " + getTarget().getWorld().name());
|
||||
thread.setPriority(Thread.MIN_PRIORITY);
|
||||
return thread;
|
||||
});
|
||||
id = engine.getCacheID();
|
||||
energy = 25;
|
||||
looper = new Looper() {
|
||||
@@ -425,16 +431,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
return;
|
||||
}
|
||||
|
||||
var ref = new WeakReference<>(e.getWorld());
|
||||
int cX = e.getX(), cZ = e.getZ();
|
||||
J.s(() -> {
|
||||
World world = ref.get();
|
||||
if (world == null || !world.isChunkLoaded(cX, cZ))
|
||||
return;
|
||||
Long key = Cache.key(e);
|
||||
cleanup.put(key, cleanupService.schedule(() -> {
|
||||
cleanup.remove(key);
|
||||
energy += 0.3;
|
||||
fixEnergy();
|
||||
getEngine().cleanupMantleChunk(cX, cZ);
|
||||
}, IrisSettings.get().getPerformance().mantleCleanupDelay);
|
||||
}, Math.max(IrisSettings.get().getPerformance().mantleCleanupDelay * 50L, 0), TimeUnit.MILLISECONDS));
|
||||
|
||||
if (generated) {
|
||||
//INMS.get().injectBiomesFromMantle(e, getMantle());
|
||||
@@ -458,6 +462,14 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChunkUnload(Chunk e) {
|
||||
final var future = cleanup.remove(Cache.key(e));
|
||||
if (future != null) {
|
||||
future.cancel(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawn(IrisPosition block, IrisSpawner spawner, boolean initial) {
|
||||
if (getEngine().isClosed()) {
|
||||
return;
|
||||
|
||||
@@ -1000,7 +1000,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
|
||||
|
||||
default void cleanupMantleChunk(int x, int z) {
|
||||
if (IrisSettings.get().getPerformance().isTrimMantleInStudio() || !isStudio()) {
|
||||
J.a(() -> getMantle().cleanupChunk(x, z));
|
||||
getMantle().cleanupChunk(x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.event.world.WorldSaveEvent;
|
||||
import org.bukkit.event.world.WorldUnloadEvent;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
@@ -125,6 +126,13 @@ public abstract class EngineAssignedWorldManager extends EngineAssignedComponent
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ChunkUnloadEvent e) {
|
||||
if (e.getChunk().getWorld().equals(getTarget().getWorld().realWorld())) {
|
||||
onChunkUnload(e.getChunk());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
super.close();
|
||||
|
||||
@@ -45,6 +45,8 @@ public interface EngineWorldManager {
|
||||
|
||||
void onChunkLoad(Chunk e, boolean generated);
|
||||
|
||||
void onChunkUnload(Chunk e);
|
||||
|
||||
void chargeEnergy();
|
||||
|
||||
void teleportAsync(PlayerTeleportEvent e);
|
||||
|
||||
Reference in New Issue
Block a user