Compare commits
2 commits
f880122add
...
5284dfe17b
Author | SHA1 | Date | |
---|---|---|---|
5284dfe17b | |||
8ea4594e6f |
3 changed files with 78 additions and 0 deletions
|
@ -32,6 +32,7 @@ import de.staropensource.sosengine.base.exceptions.dependency.UnmetDependenciesE
|
|||
import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent;
|
||||
import de.staropensource.sosengine.base.internal.types.DependencySubsystemVector;
|
||||
import de.staropensource.sosengine.base.logging.CrashHandler;
|
||||
import de.staropensource.sosengine.base.logging.InitLogger;
|
||||
import de.staropensource.sosengine.base.logging.Logger;
|
||||
import de.staropensource.sosengine.base.logging.LoggerInstance;
|
||||
import de.staropensource.sosengine.base.types.DependencyVector;
|
||||
|
@ -40,6 +41,7 @@ import de.staropensource.sosengine.base.types.immutable.ImmutableLinkedList;
|
|||
import de.staropensource.sosengine.base.utility.DependencyResolver;
|
||||
import de.staropensource.sosengine.base.utility.Miscellaneous;
|
||||
import de.staropensource.sosengine.base.utility.PlaceholderEngine;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -150,6 +152,36 @@ public final class Engine extends SubsystemClass {
|
|||
@Setter
|
||||
private @NotNull ShutdownHandler shutdownHandler = new Engine.JvmShutdownHandler();
|
||||
|
||||
/**
|
||||
* Contains the JVM shutdown hook thread,
|
||||
* which ensures that the engine is fully shut
|
||||
* down before the JVM exits.
|
||||
*
|
||||
* @see EngineInternals#installSafetyShutdownHook(boolean)
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
@Getter(AccessLevel.MODULE)
|
||||
private final @NotNull Thread safetyShutdownHook = Thread.ofPlatform()
|
||||
.name("Engine shutdown thread")
|
||||
.group(getThreadGroup())
|
||||
.unstarted(() -> {
|
||||
// Check if already shutting down
|
||||
switch (state) {
|
||||
case UNKNOWN, SHUTDOWN, CRASHED -> {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Print warning about shutdown
|
||||
logger.warn("Trying to shut down engine using shutdown hook.\nThis approach to shutting down the engine and JVM is NOT RECOMMENDED, please use Engine#shutdown() instead.");
|
||||
|
||||
// Shutdown
|
||||
Engine.getInstance().shutdown();
|
||||
|
||||
// Print last message
|
||||
InitLogger.warn(getClass(), "ENGINE", EngineInformation.getVersioningCodename(), "Engine successfully shut down using shutdown hook. PLEASE USE Engine#shutdown() INSTEAD OF System#exit() or Runtime#exit()!");
|
||||
});
|
||||
|
||||
/**
|
||||
* Initializes the StarOpenSource Engine.
|
||||
*
|
||||
|
@ -172,6 +204,7 @@ public final class Engine extends SubsystemClass {
|
|||
initializeClasses(); // Initialize classes
|
||||
if (checkEnvironment()) // Check environment
|
||||
throw new IllegalStateException("Running in an incompatible environment");
|
||||
ensureEnvironment(); // Prepare the environment and ensure safety
|
||||
populateCrashContent(); // Populate crash content
|
||||
cacheEvents(); // Cache event listeners
|
||||
startThreads(); // Start threads
|
||||
|
@ -224,6 +257,15 @@ public final class Engine extends SubsystemClass {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the execution safety of the environment.
|
||||
*
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
private void ensureEnvironment() {
|
||||
EngineInternals.getInstance().installSafetyShutdownHook(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method populates {@link CrashHandler#crashContent} with content.
|
||||
*
|
||||
|
@ -432,6 +474,11 @@ public final class Engine extends SubsystemClass {
|
|||
// Flush log messages
|
||||
Logger.flushLogMessages();
|
||||
|
||||
// Disable safety shutdown hook
|
||||
try {
|
||||
Runtime.getRuntime().removeShutdownHook(safetyShutdownHook);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
// Send events
|
||||
logger.verb("Notifiying classes about shutdown");
|
||||
new EngineShutdownEvent().callEvent();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
package de.staropensource.sosengine.base;
|
||||
|
||||
import de.staropensource.sosengine.base.exceptions.NoAccessException;
|
||||
import de.staropensource.sosengine.base.logging.LoggerInstance;
|
||||
import de.staropensource.sosengine.base.types.InternalAccessArea;
|
||||
import lombok.Getter;
|
||||
|
@ -91,4 +92,26 @@ public final class EngineInternals {
|
|||
|
||||
restrictedAreas.add(area);
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs or uninstalls the JVM shutdown
|
||||
* hook, which prevents the JVM from exiting
|
||||
* before the engine has fully shut down.
|
||||
* Highly recommended to keep enabled.
|
||||
*
|
||||
* @param status {@code true} to install, {@code false} otherwise
|
||||
* @throws NoAccessException when restricted
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
public void installSafetyShutdownHook(boolean status) throws NoAccessException {
|
||||
if (restrictedAreas.contains(InternalAccessArea.SAFETY_SHUTDOWN_HOOK))
|
||||
throw new NoAccessException("The internal access area SAFETY_SHUTDOWN_HOOK has been restricted");
|
||||
|
||||
try {
|
||||
if (status)
|
||||
Runtime.getRuntime().addShutdownHook(Engine.getInstance().getSafetyShutdownHook());
|
||||
else
|
||||
Runtime.getRuntime().removeShutdownHook(Engine.getInstance().getSafetyShutdownHook());
|
||||
} catch (IllegalArgumentException | IllegalStateException ignored) {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,4 +35,12 @@ public enum InternalAccessArea {
|
|||
* @since v1-alpha4
|
||||
*/
|
||||
ALL,
|
||||
|
||||
/**
|
||||
* Refers to the toggling of the JVM shutdown hook, which
|
||||
* prevents JVM shutdowns without the engine first shutting down.
|
||||
*
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
SAFETY_SHUTDOWN_HOOK,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue