Compare commits

...

2 commits

Author SHA1 Message Date
5284dfe17b
Remove 1s thread sleep
Some checks failed
build-and-test / build (push) Failing after 2m46s
build-and-test / generate-javadoc (push) Failing after 2m3s
build-and-test / test (push) Failing after 2m57s
2024-08-21 01:51:13 +02:00
8ea4594e6f
Revert "Removed safety shutdown hook again"
Found a fix.
This reverts commit f880122add.
2024-08-21 01:50:49 +02:00
3 changed files with 78 additions and 0 deletions

View file

@ -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();

View file

@ -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) {}
}
}

View file

@ -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,
}