mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-22 08:07:42 +00:00
Fail-closed modded decoration
- A generator with a refused or stopping engine refuses imported feature settings - Those settings no longer fall back to vanilla ones - Decoration fails when a sealed runtime has no settled feature table - Decoration fails when the feature table was retired before placement - Stacked initial spawns fail when the surface spawn biome lookup is rejected - Those spawns no longer fall back to the chunk's top biome - Bind failures from a stopping runtime stay out of the refusal memo and banner - The next bind after such a failure retries
This commit is contained in:
1 parent
0cb3417755
commit
96a400b585
8 files changed
+258
-51
No files matched your search
@@ -8,6 +8,7 @@ import java.nio.channels.ClosedChannelException;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Separates failures of the engine, its mantle, generation history, executors or the JVM from failures of one
|
||||
@@ -22,22 +23,32 @@ public final class GenerationFailures {
|
||||
}
|
||||
|
||||
public static boolean isEngineFailure(Throwable failure) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
return true;
|
||||
}
|
||||
return isShutdownFailure(failure) || hasCause(failure, (Throwable cause) -> cause instanceof Error
|
||||
|| cause instanceof WrongEngineBroException
|
||||
|| cause instanceof SavedBiomeUnavailableException unavailable && unavailable.isLoading()
|
||||
|| cause instanceof TimeoutException);
|
||||
}
|
||||
|
||||
/**
|
||||
* The engine failures that only mean a runtime, pool or thread is stopping. They say nothing about the world, so
|
||||
* nothing may remember them against it once the next runtime is up.
|
||||
*/
|
||||
public static boolean isShutdownFailure(Throwable failure) {
|
||||
return Thread.currentThread().isInterrupted() || hasCause(failure, (Throwable cause) ->
|
||||
cause instanceof GenerationClosedException
|
||||
|| cause instanceof MantleClosedException
|
||||
|| cause instanceof GenerationSessionException session && session.isExpectedTeardown()
|
||||
|| cause instanceof InterruptedException
|
||||
|| cause instanceof InterruptedIOException
|
||||
|| cause instanceof ClosedChannelException
|
||||
|| cause instanceof RejectedExecutionException
|
||||
|| cause instanceof CancellationException);
|
||||
}
|
||||
|
||||
private static boolean hasCause(Throwable failure, Predicate<Throwable> match) {
|
||||
Throwable current = failure;
|
||||
for (int depth = 0; current != null && depth < MAXIMUM_CAUSE_DEPTH; depth++, current = current.getCause()) {
|
||||
if (current instanceof Error
|
||||
|| current instanceof GenerationClosedException
|
||||
|| current instanceof MantleClosedException
|
||||
|| current instanceof WrongEngineBroException
|
||||
|| current instanceof SavedBiomeUnavailableException unavailable && unavailable.isLoading()
|
||||
|| current instanceof InterruptedException
|
||||
|| current instanceof InterruptedIOException
|
||||
|| current instanceof ClosedChannelException
|
||||
|| current instanceof RejectedExecutionException
|
||||
|| current instanceof CancellationException
|
||||
|| current instanceof TimeoutException) {
|
||||
if (match.test(current)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import art.arcane.iris.world.history.SavedBiomeUnavailableException;
|
||||
import art.arcane.volmlib.util.mantle.MantleClosedException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
@@ -52,6 +53,33 @@ public class GenerationFailuresTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shutdownFailuresAreTheLifecycleSubsetOfEngineFailures() {
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new GenerationClosedException("router closed")));
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new MantleClosedException("Tectonic Plate is closed!")));
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new RejectedExecutionException("pool shut down")));
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new ClosedByInterruptException()));
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new GenerationSessionException("sealed", true)));
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new IllegalStateException("bind failed",
|
||||
new CompletionException(new InterruptedException()))));
|
||||
|
||||
assertFalse(GenerationFailures.isShutdownFailure(new OutOfMemoryError()));
|
||||
assertFalse(GenerationFailures.isShutdownFailure(new NoClassDefFoundError("art/arcane/Missing")));
|
||||
assertFalse(GenerationFailures.isShutdownFailure(new GenerationSessionException("wrong engine")));
|
||||
assertFalse(GenerationFailures.isShutdownFailure(new IllegalStateException(
|
||||
"Iris generation history is unusable", new IOException("registry definition changed"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void anyFailureOnAnInterruptedThreadIsAShutdownFailure() {
|
||||
Thread.currentThread().interrupt();
|
||||
try {
|
||||
assertTrue(GenerationFailures.isShutdownFailure(new IllegalStateException("history unusable")));
|
||||
} finally {
|
||||
Thread.interrupted();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rethrowPropagatesEngineFailuresAndReturnsForContentFailures() {
|
||||
GenerationClosedException closed = new GenerationClosedException("router closed");
|
||||
|
||||
Reference in new issue
Block a user