mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-03 08:26:11 +00:00
revert previous
This commit is contained in:
parent
b0f4b29a2d
commit
11ae48bea1
@ -25,10 +25,7 @@ import com.volmit.iris.util.json.JSONException;
|
|||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.experimental.Accessors;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -45,7 +42,6 @@ public class IrisSettings {
|
|||||||
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
||||||
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
||||||
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
||||||
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
|
||||||
|
|
||||||
public static int getThreadCount(int c) {
|
public static int getThreadCount(int c) {
|
||||||
return switch (c) {
|
return switch (c) {
|
||||||
@ -146,30 +142,11 @@ public class IrisSettings {
|
|||||||
public int resourceLoaderCacheSize = 1_024;
|
public int resourceLoaderCacheSize = 1_024;
|
||||||
public int objectLoaderCacheSize = 4_096;
|
public int objectLoaderCacheSize = 4_096;
|
||||||
public int scriptLoaderCacheSize = 512;
|
public int scriptLoaderCacheSize = 512;
|
||||||
}
|
public double updaterThreadMultiplier = 1.0;
|
||||||
|
|
||||||
@Data
|
public double getUpdaterThreadMultiplier() {
|
||||||
public static class IrisSettingsUpdater {
|
return Math.min(Math.abs(updaterThreadMultiplier), 0.1);
|
||||||
public double threadMultiplier = 2;
|
|
||||||
public double chunkLoadSensitivity = 0.7;
|
|
||||||
public MsRange emptyMsRange = new MsRange(80, 100);
|
|
||||||
public MsRange defaultMsRange = new MsRange(20, 40);
|
|
||||||
|
|
||||||
public double getThreadMultiplier() {
|
|
||||||
return Math.min(Math.abs(threadMultiplier), 0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getChunkLoadSensitivity() {
|
|
||||||
return Math.min(chunkLoadSensitivity, 0.9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@AllArgsConstructor
|
|
||||||
public static class MsRange {
|
|
||||||
public int min = 20;
|
|
||||||
public int max = 40;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@ -10,9 +10,9 @@ import com.volmit.iris.util.mantle.MantleFlag;
|
|||||||
import com.volmit.iris.util.math.M;
|
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.profile.LoadBalancer;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import lombok.Data;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
@ -35,11 +35,10 @@ public class ChunkUpdater {
|
|||||||
private final AtomicInteger chunksProcessed = new AtomicInteger();
|
private final AtomicInteger chunksProcessed = new AtomicInteger();
|
||||||
private final AtomicInteger chunksProcessedLast = new AtomicInteger();
|
private final AtomicInteger chunksProcessedLast = new AtomicInteger();
|
||||||
private final AtomicInteger chunksUpdated = new AtomicInteger();
|
private final AtomicInteger chunksUpdated = new AtomicInteger();
|
||||||
private final AtomicBoolean serverEmpty = new AtomicBoolean(true);
|
|
||||||
private final AtomicLong lastCpsTime = new AtomicLong(M.ms());
|
private final AtomicLong lastCpsTime = new AtomicLong(M.ms());
|
||||||
private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * getProperty(), 1);
|
private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * getProperty(), 1);
|
||||||
private final Semaphore semaphore = new Semaphore(256);
|
private final Semaphore semaphore = new Semaphore(256);
|
||||||
private final LoadBalancer loadBalancer = new LoadBalancer(semaphore, 256, IrisSettings.get().getUpdater().emptyMsRange);
|
private final PlayerCounter playerCounter = new PlayerCounter(semaphore, 256);
|
||||||
private final AtomicLong startTime = new AtomicLong();
|
private final AtomicLong startTime = new AtomicLong();
|
||||||
private final Dimensions dimensions;
|
private final Dimensions dimensions;
|
||||||
private final PregenTask task;
|
private final PregenTask task;
|
||||||
@ -108,12 +107,7 @@ public class ChunkUpdater {
|
|||||||
}
|
}
|
||||||
}, 0, 3, TimeUnit.SECONDS);
|
}, 0, 3, TimeUnit.SECONDS);
|
||||||
scheduler.scheduleAtFixedRate(this::unloadChunks, 0, 1, TimeUnit.SECONDS);
|
scheduler.scheduleAtFixedRate(this::unloadChunks, 0, 1, TimeUnit.SECONDS);
|
||||||
scheduler.scheduleAtFixedRate(() -> {
|
scheduler.scheduleAtFixedRate(playerCounter::update, 0, 5, TimeUnit.SECONDS);
|
||||||
boolean empty = Bukkit.getOnlinePlayers().isEmpty();
|
|
||||||
if (serverEmpty.getAndSet(empty) == empty)
|
|
||||||
return;
|
|
||||||
loadBalancer.setRange(empty ? IrisSettings.get().getUpdater().emptyMsRange : IrisSettings.get().getUpdater().defaultMsRange);
|
|
||||||
}, 0, 10, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
var t = new Thread(() -> {
|
var t = new Thread(() -> {
|
||||||
run();
|
run();
|
||||||
@ -129,7 +123,7 @@ public class ChunkUpdater {
|
|||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
loadBalancer.close();
|
playerCounter.close();
|
||||||
semaphore.acquire(256);
|
semaphore.acquire(256);
|
||||||
|
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
@ -340,7 +334,35 @@ public class ChunkUpdater {
|
|||||||
|
|
||||||
private record Dimensions(Position2 min, Position2 max, int count, PregenTask task) { }
|
private record Dimensions(Position2 min, Position2 max, int count, PregenTask task) { }
|
||||||
|
|
||||||
|
@Data
|
||||||
|
private static class PlayerCounter {
|
||||||
|
private final Semaphore semaphore;
|
||||||
|
private final int maxPermits;
|
||||||
|
private int lastCount = 0;
|
||||||
|
private int permits = 0;
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
double count = Bukkit.getOnlinePlayers().size();
|
||||||
|
if (count == lastCount)
|
||||||
|
return;
|
||||||
|
double p = count == 0 ? 0 : count / (Bukkit.getMaxPlayers() / 2d);
|
||||||
|
int targetPermits = (int) (maxPermits * p);
|
||||||
|
|
||||||
|
int diff = targetPermits - permits;
|
||||||
|
permits = targetPermits;
|
||||||
|
lastCount = (int) count;
|
||||||
|
try {
|
||||||
|
if (diff > 0) semaphore.release(diff);
|
||||||
|
else semaphore.acquire(Math.abs(diff));
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
semaphore.release(permits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static double getProperty() {
|
private static double getProperty() {
|
||||||
return IrisSettings.get().getUpdater().getThreadMultiplier();
|
return IrisSettings.get().getPerformance().getUpdaterThreadMultiplier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
package com.volmit.iris.util.profile;
|
|
||||||
|
|
||||||
|
|
||||||
import com.volmit.iris.core.IrisSettings;
|
|
||||||
import com.volmit.iris.util.math.M;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.java.Log;
|
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
|
|
||||||
@Log
|
|
||||||
@Getter
|
|
||||||
public class LoadBalancer extends MsptTimings {
|
|
||||||
private final Semaphore semaphore;
|
|
||||||
private final int maxPermits;
|
|
||||||
private final double range;
|
|
||||||
@Setter
|
|
||||||
private int minMspt, maxMspt;
|
|
||||||
private int permits, lastMspt;
|
|
||||||
private long lastTime = M.ms();
|
|
||||||
private Future<?> future;
|
|
||||||
|
|
||||||
public LoadBalancer(Semaphore semaphore, int maxPermits, IrisSettings.MsRange range) {
|
|
||||||
this(semaphore, maxPermits, range.getMin(), range.getMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoadBalancer(Semaphore semaphore, int maxPermits, int minMspt, int maxMspt) {
|
|
||||||
this.semaphore = semaphore;
|
|
||||||
this.maxPermits = maxPermits;
|
|
||||||
this.minMspt = minMspt;
|
|
||||||
this.maxMspt = maxMspt;
|
|
||||||
this.range = maxMspt - minMspt;
|
|
||||||
setName("LoadBalancer");
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void update(int raw) {
|
|
||||||
lastTime = M.ms();
|
|
||||||
int mspt = raw;
|
|
||||||
if (mspt < lastMspt) {
|
|
||||||
int min = (int) Math.max(lastMspt * IrisSettings.get().getUpdater().getChunkLoadSensitivity(), 1);
|
|
||||||
mspt = Math.max(mspt, min);
|
|
||||||
}
|
|
||||||
lastMspt = mspt;
|
|
||||||
mspt = Math.max(mspt - minMspt, 0);
|
|
||||||
double percent = mspt / range;
|
|
||||||
|
|
||||||
int target = (int) (maxPermits * percent);
|
|
||||||
target = Math.min(target, maxPermits - 20);
|
|
||||||
|
|
||||||
int diff = target - permits;
|
|
||||||
permits = target;
|
|
||||||
|
|
||||||
if (diff == 0) return;
|
|
||||||
log.info("Adjusting load to %s (%s) permits (%s mspt, %.2f)".formatted(target, diff, raw, percent));
|
|
||||||
|
|
||||||
if (diff > 0) semaphore.acquireUninterruptibly(diff);
|
|
||||||
else semaphore.release(Math.abs(diff));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
interrupt();
|
|
||||||
semaphore.release(permits);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRange(IrisSettings.MsRange range) {
|
|
||||||
minMspt = range.getMin();
|
|
||||||
maxMspt = range.getMax();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package com.volmit.iris.util.profile;
|
|
||||||
|
|
||||||
import com.volmit.iris.util.math.M;
|
|
||||||
import com.volmit.iris.util.scheduling.J;
|
|
||||||
import com.volmit.iris.util.scheduling.Looper;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public abstract class MsptTimings extends Looper {
|
|
||||||
private final AtomicInteger currentTick = new AtomicInteger(0);
|
|
||||||
private int lastTick, lastMspt;
|
|
||||||
private long lastTime;
|
|
||||||
private int taskId = -1;
|
|
||||||
|
|
||||||
public MsptTimings() {
|
|
||||||
setName("MsptTimings");
|
|
||||||
setPriority(9);
|
|
||||||
setDaemon(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MsptTimings of(Consumer<Integer> update) {
|
|
||||||
return new Simple(update);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected final long loop() {
|
|
||||||
if (startTickTask())
|
|
||||||
return 200;
|
|
||||||
|
|
||||||
long now = M.ms();
|
|
||||||
int tick = currentTick.get();
|
|
||||||
int deltaTick = tick - lastTick;
|
|
||||||
if (deltaTick == 0)
|
|
||||||
return 200;
|
|
||||||
lastTick = tick;
|
|
||||||
int deltaTime = (int) (now - lastTime);
|
|
||||||
lastTime = now;
|
|
||||||
int mspt = deltaTime / deltaTick;
|
|
||||||
mspt -= 50;
|
|
||||||
mspt = Math.max(mspt, 0);
|
|
||||||
lastMspt = mspt;
|
|
||||||
update(mspt);
|
|
||||||
return 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final int getMspt() {
|
|
||||||
return lastMspt;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void update(int mspt);
|
|
||||||
|
|
||||||
private boolean startTickTask() {
|
|
||||||
if (taskId != -1 && (Bukkit.getScheduler().isQueued(taskId) || Bukkit.getScheduler().isCurrentlyRunning(taskId)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
taskId = J.sr(() -> {
|
|
||||||
if (isInterrupted()) {
|
|
||||||
J.csr(taskId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTick.incrementAndGet();
|
|
||||||
}, 1);
|
|
||||||
return taskId != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Simple extends MsptTimings {
|
|
||||||
private final Consumer<Integer> update;
|
|
||||||
|
|
||||||
private Simple(Consumer<Integer> update) {
|
|
||||||
this.update = update;
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void update(int mspt) {
|
|
||||||
if (update == null)
|
|
||||||
return;
|
|
||||||
update.accept(mspt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user