mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Drained pregen before shutdown
- Server shutdown advances native chunk tasks while waiting for pregeneration - Native world close owns chunk saves during server shutdown - Pending plugin flushes stop waiting when native shutdown begins - Late eviction completion cannot schedule another shutdown flush - Regression tests cover owner waits and shutdown save ownership
This commit is contained in:
1 parent
319f8aed47
commit
083e689864
6 files changed
+420
-4
No files matched your search
@@ -208,6 +208,28 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
return shutdownAndWait(inst, timeoutMs);
|
||||
}
|
||||
|
||||
public static boolean shutdownAndWait(long timeoutMs, Runnable processPendingTasks) {
|
||||
Objects.requireNonNull(processPendingTasks, "processPendingTasks");
|
||||
PregeneratorJob inst = instance.get();
|
||||
if (inst == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inst.requestStop();
|
||||
long started = System.nanoTime();
|
||||
long timeoutNanos = TimeUnit.MILLISECONDS.toNanos(Math.max(1L, timeoutMs));
|
||||
try {
|
||||
while (inst.worker.isAlive() && System.nanoTime() - started < timeoutNanos) {
|
||||
processPendingTasks.run();
|
||||
inst.worker.join(1L);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IllegalStateException("Interrupted while stopping the Iris pregenerator.", e);
|
||||
}
|
||||
return finishShutdown(inst, timeoutMs);
|
||||
}
|
||||
|
||||
private static boolean shutdownAndWait(PregeneratorJob inst, long timeoutMs) {
|
||||
inst.requestStop();
|
||||
try {
|
||||
@@ -216,6 +238,10 @@ public class PregeneratorJob implements PregenListener, PregenRenderSource {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IllegalStateException("Interrupted while stopping the Iris pregenerator.", e);
|
||||
}
|
||||
return finishShutdown(inst, timeoutMs);
|
||||
}
|
||||
|
||||
private static boolean finishShutdown(PregeneratorJob inst, long timeoutMs) {
|
||||
if (inst.worker.isAlive()) {
|
||||
throw new IllegalStateException("Timed out while stopping the Iris pregenerator after "
|
||||
+ Math.max(1L, timeoutMs) + "ms.");
|
||||
|
||||
+25
-2
@@ -357,6 +357,9 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> evictRegion(long c) {
|
||||
if (IrisToolbelt.isServerStopping()) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
if (!evictedRegions.add(c)) {
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
@@ -441,6 +444,9 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
}
|
||||
|
||||
private void flushAllRemainingChunks() {
|
||||
if (IrisToolbelt.isServerStopping()) {
|
||||
return;
|
||||
}
|
||||
List<Long> keys = new ArrayList<>(regionChunks.keySet());
|
||||
List<CompletableFuture<Void>> evictions = new ArrayList<>(keys.size() + pendingEvictions.size());
|
||||
for (Long regionKey : keys) {
|
||||
@@ -453,10 +459,27 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
||||
CompletableFuture<Void> settledEvictions = evictionsComplete.handle((ignored, failure) -> null);
|
||||
CompletableFuture<Void> flush = foliaRuntime
|
||||
? settledEvictions
|
||||
: settledEvictions.thenCompose(ignored -> J.sfut(() -> INMS.get().flushChunkIO(world)));
|
||||
: settledEvictions.thenCompose(ignored -> IrisToolbelt.isServerStopping()
|
||||
? CompletableFuture.completedFuture(null)
|
||||
: J.sfut(() -> INMS.get().flushChunkIO(world)));
|
||||
|
||||
long started = System.nanoTime();
|
||||
long timeoutNanos = TimeUnit.SECONDS.toNanos(FLUSH_TIMEOUT_SECONDS);
|
||||
try {
|
||||
flush.get(FLUSH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
while (!IrisToolbelt.isServerStopping()) {
|
||||
long remaining = timeoutNanos - (System.nanoTime() - started);
|
||||
if (remaining <= 0L) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
try {
|
||||
flush.get(Math.min(remaining, TimeUnit.MILLISECONDS.toNanos(100L)), TimeUnit.NANOSECONDS);
|
||||
return;
|
||||
} catch (TimeoutException e) {
|
||||
if (System.nanoTime() - started >= timeoutNanos) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
IrisLogging.warn("Interrupted while flushing pregen chunks for " + world.getName() + ".");
|
||||
|
||||
Reference in new issue
Block a user