- Fixed LazyPregenerator.java and improved it. ( Speed decrease on server restart when lazy starts the job up dont know why)

- Mem leak fix only works when there is 1 iris world for now ( working on it ) + A capped performance limit still very alpha like seems stable tho.

- Disabled HotDropWorldSVC acts a bit weird sometimes.
This commit is contained in:
RePixelatedMC
2023-12-15 19:06:53 +01:00
parent 57c647fa0e
commit 54ae026c2b
6 changed files with 215 additions and 113 deletions
@@ -34,6 +34,7 @@ import org.bukkit.World;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.File; import java.io.File;
import java.io.IOException;
@Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!") @Decree(name = "lazypregen", aliases = "lazy", description = "Pregenerate your Iris worlds!")
public class CommandLazyPregen implements DecreeExecutor { public class CommandLazyPregen implements DecreeExecutor {
@@ -53,6 +54,14 @@ public class CommandLazyPregen implements DecreeExecutor {
) { ) {
worldName = world.getName(); worldName = world.getName();
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
File lazyFile = new File(worldDirectory, "lazygen.json");
if (lazyFile.exists()) {
sender().sendMessage(C.BLUE + "Lazy pregen is already in progress");
Iris.info(C.YELLOW + "Lazy pregen is already in progress");
return;
}
try { try {
if (sender().isPlayer() && access() == null) { if (sender().isPlayer() && access() == null) {
sender().sendMessage(C.RED + "The engine access for this world is null!"); sender().sendMessage(C.RED + "The engine access for this world is null!");
@@ -69,7 +78,6 @@ public class CommandLazyPregen implements DecreeExecutor {
.silent(silent) .silent(silent)
.build(); .build();
File worldDirectory = new File(Bukkit.getWorldContainer(), worldName);
File lazyGenFile = new File(worldDirectory, "lazygen.json"); File lazyGenFile = new File(worldDirectory, "lazygen.json");
LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, lazyGenFile); LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, lazyGenFile);
pregenerator.start(); pregenerator.start();
@@ -85,20 +93,26 @@ public class CommandLazyPregen implements DecreeExecutor {
} }
@Decree(description = "Stop the active pregeneration task", aliases = "x") @Decree(description = "Stop the active pregeneration task", aliases = "x")
public void stop() { public void stop(
@Param(aliases = "world", description = "The world to pause")
World world
) throws IOException {
if (LazyPregenerator.getInstance() != null) { if (LazyPregenerator.getInstance() != null) {
LazyPregenerator.getInstance().shutdownInstance(); LazyPregenerator.getInstance().shutdownInstance(world);
Iris.info( C.BLUE + "Shutting down all Lazy Pregens"); sender().sendMessage(C.LIGHT_PURPLE + "Closed lazygen instance for " + world.getName());
} else { } else {
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop"); sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
} }
} }
@Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"}) @Decree(description = "Pause / continue the active pregeneration task", aliases = {"t", "resume", "unpause"})
public void pause() { public void pause(
@Param(aliases = "world", description = "The world to pause")
World world
) {
if (LazyPregenerator.getInstance() != null) { if (LazyPregenerator.getInstance() != null) {
LazyPregenerator.getInstance().setPausedLazy(); LazyPregenerator.getInstance().setPausedLazy(world);
sender().sendMessage(C.GREEN + "Paused/unpaused Lazy Pregen, now: " + (LazyPregenerator.getInstance().isPausedLazy() ? "Paused" : "Running") + "."); sender().sendMessage(C.GREEN + "Paused/unpaused Lazy Pregen, now: " + (LazyPregenerator.getInstance().isPausedLazy(world) ? "Paused" : "Running") + ".");
} else { } else {
sender().sendMessage(C.YELLOW + "No active Lazy Pregen tasks to pause/unpause."); sender().sendMessage(C.YELLOW + "No active Lazy Pregen tasks to pause/unpause.");
@@ -2,8 +2,6 @@ package com.volmit.iris.core.pregenerator;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.PregeneratorJob;
import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form; import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.io.IO; import com.volmit.iris.util.io.IO;
@@ -11,11 +9,8 @@ import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.math.Spiraler; import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.J;
import io.lumine.mythic.bukkit.utils.lib.jooq.False;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
@@ -25,23 +20,26 @@ import org.bukkit.World;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import java.util.HashMap;
import java.util.Map;
public class LazyPregenerator extends Thread implements Listener { public class LazyPregenerator extends Thread implements Listener {
@Getter @Getter
private static LazyPregenerator instance; private static LazyPregenerator instance;
private final LazyPregenJob job; private final LazyPregenJob job;
private final File destination; private final File destination;
private final int maxPosition; private final int maxPosition;
private final World world; private World world;
private final long rate; private final long rate;
private final ChronoLatch latch; private final ChronoLatch latch;
private static AtomicInteger lazyGeneratedChunks; private static AtomicInteger lazyGeneratedChunks;
@@ -49,6 +47,10 @@ public class LazyPregenerator extends Thread implements Listener {
private final AtomicInteger lazyTotalChunks; private final AtomicInteger lazyTotalChunks;
private final AtomicLong startTime; private final AtomicLong startTime;
private final RollingSequence chunksPerSecond; private final RollingSequence chunksPerSecond;
private final RollingSequence chunksPerMinute;
// A map to keep track of jobs for each world
private static final Map<String, LazyPregenJob> jobs = new HashMap<>();
public LazyPregenerator(LazyPregenJob job, File destination) { public LazyPregenerator(LazyPregenJob job, File destination) {
this.job = job; this.job = job;
@@ -56,13 +58,15 @@ public class LazyPregenerator extends Thread implements Listener {
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> { this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
}).count(); }).count();
this.world = Bukkit.getWorld(job.getWorld()); this.world = Bukkit.getWorld(job.getWorld());
this.rate = Math.round((1D / (job.chunksPerMinute / 60D)) * 1000D); this.rate = Math.round((1D / (job.getChunksPerMinute() / 60D)) * 1000D);
this.latch = new ChronoLatch(6000); this.latch = new ChronoLatch(15000);
startTime = new AtomicLong(M.ms()); this.startTime = new AtomicLong(M.ms());
chunksPerSecond = new RollingSequence(10); this.chunksPerSecond = new RollingSequence(10);
this.chunksPerMinute = new RollingSequence(10);
lazyGeneratedChunks = new AtomicInteger(0); lazyGeneratedChunks = new AtomicInteger(0);
generatedLast = new AtomicInteger(0); this.generatedLast = new AtomicInteger(0);
lazyTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2))); this.lazyTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
jobs.put(job.getWorld(), job);
LazyPregenerator.instance = this; LazyPregenerator.instance = this;
} }
@@ -73,7 +77,6 @@ public class LazyPregenerator extends Thread implements Listener {
public static void loadLazyGenerators() { public static void loadLazyGenerators() {
for (World i : Bukkit.getWorlds()) { for (World i : Bukkit.getWorlds()) {
File lazygen = new File(i.getWorldFolder(), "lazygen.json"); File lazygen = new File(i.getWorldFolder(), "lazygen.json");
if (lazygen.exists()) { if (lazygen.exists()) {
try { try {
LazyPregenerator p = new LazyPregenerator(lazygen); LazyPregenerator p = new LazyPregenerator(lazygen);
@@ -107,15 +110,17 @@ public class LazyPregenerator extends Thread implements Listener {
} }
public void tick() { public void tick() {
LazyPregenJob job = jobs.get(world.getName());
if (latch.flip() && !job.paused) { if (latch.flip() && !job.paused) {
long eta = computeETA(); long eta = computeETA();
save(); save();
int secondGenerated = lazyGeneratedChunks.get() - generatedLast.get(); int secondGenerated = lazyGeneratedChunks.get() - generatedLast.get();
generatedLast.set(lazyGeneratedChunks.get()); generatedLast.set(lazyGeneratedChunks.get());
secondGenerated = secondGenerated / 6; secondGenerated = secondGenerated / 15;
chunksPerSecond.put(secondGenerated); chunksPerSecond.put(secondGenerated);
chunksPerMinute.put(secondGenerated * 60);
if (!job.isSilent()) { if (!job.isSilent()) {
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(lazyGeneratedChunks.get()) + " of " + Form.f(lazyTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2)); Iris.info("LazyGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(lazyGeneratedChunks.get()) + " of " + Form.f(lazyTotalChunks.get()) + " " + Form.f((int) chunksPerMinute.getAverage()) + "/m ETA: " + Form.duration((double) eta, 2));
} }
} }
@@ -138,12 +143,8 @@ public class LazyPregenerator extends Thread implements Listener {
} }
private long computeETA() { private long computeETA() {
return (long) (lazyTotalChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total? return (long) ((lazyTotalChunks.get() - lazyGeneratedChunks.get()) / chunksPerMinute.getAverage()) * 1000;
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers) // todo broken
((lazyTotalChunks.get() - lazyGeneratedChunks.get()) * ((double) (M.ms() - startTime.get()) / (double) lazyGeneratedChunks.get())) :
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
((lazyTotalChunks.get() - lazyGeneratedChunks.get()) / chunksPerSecond.getAverage()) * 1000 //
);
} }
private final ExecutorService executorService = Executors.newSingleThreadExecutor(); private final ExecutorService executorService = Executors.newSingleThreadExecutor();
@@ -154,7 +155,10 @@ public class LazyPregenerator extends Thread implements Listener {
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true) PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
.thenAccept((i) -> { .thenAccept((i) -> {
LazyPregenJob j = jobs.get(world.getName());
if (!j.paused) {
Iris.verbose("Generated Async " + chunk); Iris.verbose("Generated Async " + chunk);
}
latch.countDown(); latch.countDown();
}); });
} else { } else {
@@ -201,23 +205,64 @@ public class LazyPregenerator extends Thread implements Listener {
} }
}); });
} }
public void setPausedLazy(){
if (!job.paused) { public static void setPausedLazy(World world) {
save(); // todo: doesnt actually pause
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world + C.BLUE + " Paused"); LazyPregenJob job = jobs.get(world.getName());
job.setPaused(true); if (isPausedLazy(world)){
job.paused = false;
} else { } else {
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world + C.BLUE + " Resumes"); job.paused = true;
job.setPaused(false); }
if ( job.paused) {
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
} else {
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
} }
} }
public boolean isPausedLazy(){
return job.isPaused(); public static boolean isPausedLazy(World world) {
LazyPregenJob job = jobs.get(world.getName());
return job != null && job.isPaused();
}
public void shutdownInstance(World world) throws IOException {
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
LazyPregenJob job = jobs.get(world.getName());
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
File lazyFile = new File(worldDirectory, "lazygen.json");
if (job == null) {
Iris.error("No Lazygen job found for world: " + world.getName());
return;
}
try {
if (!job.isPaused()) {
job.setPaused(true);
} }
public void shutdownInstance() {
save(); save();
jobs.remove(world.getName());
new BukkitRunnable() {
@Override
public void run() {
while (lazyFile.exists()){
lazyFile.delete();
J.sleep(1000);
}
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
}
}.runTaskLater(Iris.instance, 20L);
} catch (Exception e) {
Iris.error("Failed to shutdown Lazygen for " + world.getName());
e.printStackTrace();
} finally {
saveNow();
interrupt(); interrupt();
} }
}
public void saveNow() throws IOException { public void saveNow() throws IOException {
IO.writeAll(this.destination, new Gson().toJson(job)); IO.writeAll(this.destination, new Gson().toJson(job));
@@ -232,7 +277,7 @@ public class LazyPregenerator extends Thread implements Listener {
@Builder.Default @Builder.Default
private boolean healing = false; private boolean healing = false;
@Builder.Default @Builder.Default
private int chunksPerMinute = 32; // 48 hours is roughly 5000 radius private int chunksPerMinute = 32;
@Builder.Default @Builder.Default
private int radiusBlocks = 5000; private int radiusBlocks = 5000;
@Builder.Default @Builder.Default
@@ -243,3 +288,4 @@ public class LazyPregenerator extends Thread implements Listener {
boolean paused = false; boolean paused = false;
} }
} }
@@ -30,7 +30,7 @@ public class HotDropWorldSVC implements IrisService {
@Override @Override
public void onEnable() { public void onEnable() {
this.plugin = Iris.instance; this.plugin = Iris.instance;
initializeWatchService(); // initializeWatchService();
} }
@Override @Override
@@ -1,68 +1,120 @@
package com.volmit.iris.core.service; package com.volmit.iris.core.service;
import com.volmit.iris.Iris; import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.platform.PlatformChunkGenerator; import com.volmit.iris.engine.platform.PlatformChunkGenerator;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.mantle.TectonicPlate;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.misc.getHardware; import com.volmit.iris.util.misc.getHardware;
import com.volmit.iris.util.parallel.BurstExecutor;
import com.volmit.iris.util.parallel.HyperLock;
import com.volmit.iris.util.parallel.MultiBurst;
import com.volmit.iris.util.plugin.IrisService; import com.volmit.iris.util.plugin.IrisService;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper; import com.volmit.iris.util.scheduling.Looper;
import io.papermc.lib.PaperLib;
import lombok.Getter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicInteger;
import static com.volmit.iris.util.mantle.Mantle.tectonicLimit; import static com.volmit.iris.util.mantle.Mantle.tectonicLimit;
public class IrisEngineSVC implements IrisService { public class IrisEngineSVC implements IrisService {
private JavaPlugin plugin; private JavaPlugin plugin;
public Looper ticker; public Looper ticker1;
public Looper ticker2;
public Looper engineTicker;
public World selectedWorld;
public List<World> IrisWorlds = new ArrayList<>(); public List<World> IrisWorlds = new ArrayList<>();
public List<World> corruptedIrisWorlds = new ArrayList<>(); public List<World> corruptedIrisWorlds = new ArrayList<>();
@Override @Override
public void onEnable() { public void onEnable() {
this.plugin = Iris.instance; this.plugin = Iris.instance;
this.IrisStartup(); tectonicLimit.set(2);
long t = getHardware.getProcessMemory();
for (; t > 250; ) {
tectonicLimit.getAndAdd(1);
t = t - 250;
}
tectonicLimit.set(10); // DEBUG CODE
this.IrisEngine(); this.IrisEngine();
ticker.start(); engineTicker.start();
ticker1.start();
ticker2.start();
}
private final AtomicReference<World> selectedWorldRef = new AtomicReference<>();
public CompletableFuture<World> initializeAsync() {
return CompletableFuture.supplyAsync(() -> {
World selectedWorld = null;
while (selectedWorld == null) {
synchronized (this) {
IrisWorlds.clear();
for (World w : Bukkit.getServer().getWorlds()) {
if (IrisToolbelt.access(w) != null) {
IrisWorlds.add(w);
}
}
if (!IrisWorlds.isEmpty()) {
Random rand = new Random();
int randomIndex = rand.nextInt(IrisWorlds.size());
selectedWorld = IrisWorlds.get(randomIndex);
}
}
if (selectedWorld == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
}
}
return selectedWorld;
});
} }
public void IrisEngine(){ public void IrisEngine(){
ticker = new Looper() { engineTicker = new Looper() {
@Override @Override
protected long loop() { protected long loop() {
try { try {
for (World world : IrisWorlds) { World world = selectedWorldRef.get();
Engine engine = IrisToolbelt.access(world).getEngine(); PlatformChunkGenerator generator = IrisToolbelt.access(world);
if(generator == null) {
initializeAsync().thenAcceptAsync(foundWorld -> selectedWorldRef.set(foundWorld));
} else {
selectedWorld = world;
} }
PlatformChunkGenerator generator = IrisToolbelt.access(Bukkit.getWorld("localmemtest")); } catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
return -1;
}
return 1000;
}
};
ticker1 = new Looper() {
@Override
protected long loop() {
try {
World world = selectedWorld;
PlatformChunkGenerator generator = IrisToolbelt.access(world);
if(generator != null) {
Engine engine = IrisToolbelt.access(world).getEngine();
if (generator != null && generator.getEngine() != null) { if (generator != null && generator.getEngine() != null) {
Engine engine = generator.getEngine();
engine.getMantle().trim(); engine.getMantle().trim();
} else { } else {
Iris.info("localmemtest is nullmem"); Iris.info("something is null 1");
}
} }
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
@@ -73,38 +125,36 @@ public class IrisEngineSVC implements IrisService {
return 1000; return 1000;
} }
}; };
}
public void IrisStartup(){ ticker2 = new Looper() {
tectonicLimit.set(2); @Override
long t = getHardware.getProcessMemory(); protected long loop() {
for (; t > 250; ) { try {
tectonicLimit.getAndAdd(1); World world = selectedWorld;
t = t - 250; PlatformChunkGenerator generator = IrisToolbelt.access(world);
} if(generator != null) {
tectonicLimit.set(10); // DEBUG CODE Engine engine = IrisToolbelt.access(world).getEngine();
if (generator != null && generator.getEngine() != null) {
for (World w : Bukkit.getServer().getWorlds()) { engine.getMantle().unloadTectonicPlate();
File container = Bukkit.getWorldContainer();
Bukkit.getWorldContainer();
if(IrisToolbelt.access(w) != null){
IrisWorlds.add(w);
} else { } else {
File worldDirectory = new File(container, w.getName()); Iris.info("something is null 2");
File IrisWorldTest = new File(worldDirectory, "Iris");
if (IrisWorldTest.exists()){
if(IrisToolbelt.access(w) == null){
corruptedIrisWorlds.add(w);
} }
} }
} catch (Throwable e) {
Iris.reportError(e);
e.printStackTrace();
return -1;
} }
return 1000;
} }
};
} }
@Override @Override
public void onDisable() { public void onDisable() {
ticker.interrupt(); ticker1.interrupt();
ticker2.interrupt();
engineTicker.interrupt();
} }
} }
@@ -178,6 +178,9 @@ public interface EngineMantle extends IObjectPlacer {
default void trim() { default void trim() {
getMantle().trim(TimeUnit.SECONDS.toMillis(IrisSettings.get().getPerformance().getMantleKeepAlive())); getMantle().trim(TimeUnit.SECONDS.toMillis(IrisSettings.get().getPerformance().getMantleKeepAlive()));
} }
default void unloadTectonicPlate(){
getMantle().unloadTectonicPlate();
}
default MultiBurst burst() { default MultiBurst burst() {
return getEngine().burst(); return getEngine().burst();
@@ -91,12 +91,6 @@ public class Mantle {
loadedRegions = new KMap<>(); loadedRegions = new KMap<>();
lastUse = new KMap<>(); lastUse = new KMap<>();
ioBurst = MultiBurst.burst; ioBurst = MultiBurst.burst;
if (!ioTectonicUnload.get()) {
this.unloadTectonicPlate();
if (!ticker.isAlive()) {
ticker.start();
}
}
Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath()); Iris.debug("Opened The Mantle " + C.DARK_AQUA + dataFolder.getAbsolutePath());
} }
@@ -421,7 +415,7 @@ public class Mantle {
if (closed.get()) { if (closed.get()) {
throw new RuntimeException("The Mantle is closed"); throw new RuntimeException("The Mantle is closed");
} }
Iris.info(C.BLUE + "TECTONIC TRIM HAS RUN"); Iris.debug(C.BLUE + "TECTONIC TRIM HAS RUN");
if (IrisSettings.get().getPerformance().getAggressiveTectonicThreshold() == -1) { if (IrisSettings.get().getPerformance().getAggressiveTectonicThreshold() == -1) {
forceAggressiveThreshold.set(tectonicLimit.get()); forceAggressiveThreshold.set(tectonicLimit.get());
} else { } else {
@@ -493,12 +487,10 @@ public class Mantle {
} }
} }
protected void unloadTectonicPlate() { public synchronized void unloadTectonicPlate() {
ticker = new Looper() {
protected long loop() {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
try { try {
Iris.info(C.DARK_BLUE + "TECTONIC UNLOAD HAS RUN"); Iris.debug(C.DARK_BLUE + "TECTONIC UNLOAD HAS RUN");
int threadCount = 1; int threadCount = 1;
ExecutorService executorService = Executors.newFixedThreadPool(threadCount); ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
List<Long> toUnloadList; List<Long> toUnloadList;
@@ -537,11 +529,8 @@ public class Mantle {
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return -1;
} }
return Math.max(0, 1000-(System.currentTimeMillis()-time));
}
};
ioTectonicUnload.set(true); ioTectonicUnload.set(true);
} }