From 04f8aa360ad3fc511feacadea5d5adf4ee8bdbd4 Mon Sep 17 00:00:00 2001 From: JeremyStarTM Date: Fri, 20 Dec 2024 01:37:03 +0100 Subject: [PATCH] Add Engine.reload method and SHUT_DOWN_FINAL state --- .../de/staropensource/engine/base/Engine.kt | 131 +++++++++++++----- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt b/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt index 67559aa..a2ebcff 100644 --- a/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt +++ b/base/src/main/kotlin/de/staropensource/engine/base/Engine.kt @@ -20,9 +20,9 @@ package de.staropensource.engine.base import de.staropensource.engine.base.exception.EngineInitializationFailureException +import de.staropensource.engine.base.logging.Logger import de.staropensource.engine.base.utility.Environment import de.staropensource.engine.base.utility.FileAccess -import de.staropensource.engine.base.logging.Logger import de.staropensource.engine.base.utility.dnihbd.BuildInformation /** @@ -45,7 +45,7 @@ class Engine private constructor() { * * @since v1-alpha10 */ - internal val logger: Logger = Logger("engine-core") + internal val logger: Logger = Logger(channel = "engine-core") /** * Contains the state the engine is in. @@ -81,7 +81,7 @@ class Engine private constructor() { var info: BuildInformation? = null - // -----> Initialization + // -----> Lifecycle /** * Bootstraps the engine. * @@ -96,6 +96,7 @@ class Engine private constructor() { @JvmStatic @Throws(Throwable::class) private fun bootstrap(): Boolean { + // Check for state if (state != State.UNINITIALIZED || bootstrapping != null) return true @@ -104,6 +105,7 @@ class Engine private constructor() { logger.info("Bootstrapping") // Run bootstrapping code + // *none yet* bootstrapping = false return true @@ -126,19 +128,19 @@ class Engine private constructor() { @JvmStatic @Throws(EngineInitializationFailureException::class) fun initialize() { - // Abort if initializing, shutting down - // or the engine has crashed - if ( - bootstrapping == true - || state == State.INITIALIZING - || state == State.SHUTTING_DOWN - || state == State.CRASHED - ) return + // Check state + if (bootstrapping == true) + return + when (state) { + State.INITIALIZING, State.SHUTTING_DOWN, State.SHUT_DOWN_FINAL, State.CRASHED -> return + else -> {} + } // Bootstrap if not already done so if (!bootstrap()) return + // Initialize try { state = State.INITIALIZING logger.info("Initializing") @@ -155,6 +157,40 @@ class Engine private constructor() { } } + /** + * Reloads the engine. + * + * The request is ignored if + * the engine isn't running. + * + * @since v1-alpha10 + */ + @JvmStatic + fun reload() { + // Check for state + if (state != State.INITIALIZED) + return + + logger.info("Reloading") + + // Run reload code + // *none yet* + + // Reload subsystems + logger.verb("Reloading subsystems") + for (subsystem: Subsystem in subsystems) + try { + logger.diag("Reloading subsystem '${subsystem.getName()}' [${subsystem::class.qualifiedName ?: ""}]") + subsystem.reload() + } catch (throwable: Throwable) { + logger.crash( + "Failed to reload subsystem '${subsystem.getName()}' [${subsystem::class.qualifiedName ?: ""}]", + throwable = throwable, + fatal = true + ) + } + } + /** * Shuts the engine down. * @@ -165,14 +201,14 @@ class Engine private constructor() { */ @JvmStatic fun shutdown() { - // Abort if not initialized + // Check for state if (state != State.INITIALIZED) return logger.info("Shutting down") // Perform shutdown - performShutdown() + performShutdown(false) state = State.SHUT_DOWN } @@ -187,17 +223,17 @@ class Engine private constructor() { */ @JvmStatic fun shutdownFinal(exitcode: UByte = 0u) { - // Abort if not initialized + // Check for state if (state != State.INITIALIZED) return logger.info("Shutting down for good") // Perform shutdown - performShutdown() - state = State.SHUT_DOWN + performShutdown(true) + state = State.SHUT_DOWN_FINAL - // Quit application + // Initiate application shutdown EngineConfiguration.shutdownHandler.exit(exitcode) } @@ -209,10 +245,16 @@ class Engine private constructor() { */ @JvmStatic internal fun shutdownAfterCrash() { + // Check for state + when (state) { + State.UNINITIALIZED, State.SHUTTING_DOWN, State.SHUT_DOWN, State.CRASHED -> return + else -> {} + } + logger.info("Shutting down after having crashed fatally") // Perform shutdown - performShutdown(crashed = true) + performShutdown(true, crashed = true) state = State.CRASHED // Quit application @@ -225,11 +267,12 @@ class Engine private constructor() { * This performs the actual shutdown, * just without the bloat. * + * @param final whether this is the last time the engine shuts down. Doesn't actually shut the application down, just changes some messages and does other things * @param crashed enables super careful mode to prevent further breakage * @since v1-alpha10 */ @JvmStatic - private fun performShutdown(crashed: Boolean = false) { + private fun performShutdown(final: Boolean, crashed: Boolean = false) { state = State.SHUTTING_DOWN // Run shutdown code @@ -267,40 +310,64 @@ class Engine private constructor() { INITIALIZING, /** - * Specifies that the engine has fully - * initialized and can be safely used. + * Specifies that the engine + * has fully initialized and + * can be safely used. * * @since v1-alpha10 */ INITIALIZED, /** - * Indicates that the engine is in - * the process of shutting down. + * Indicates that the engine + * is in the process of + * shutting itself down. * * Many methods are considered * unsafe and should not be called. + * + * @since v1-alpha10 */ SHUTTING_DOWN, /** - * Indicates that the engine has been shut down. + * Indicates that the engine has + * been shut down. * - * This may not be a final state. + * Many methods are considered + * unsafe and should not be called. + * + * This is not a final state. The + * engine may be initialized again. * * @since v1-alpha10 */ SHUT_DOWN, /** - * Indicates that the engine has crashed and - * is in a state where further usage is - * HIGHLY discouraged. Any further calls may - * cause the process or virtual machine to - * exit with a fatal error. + * Indicates that the engine + * has been shut down for good. * - * This is a final state. The engine cannot - * be initialized again after having crashed. + * This is a final state. The + * engine cannot be initialized + * again after having shut down + * final. + * + * @since v1-alpha10 + */ + SHUT_DOWN_FINAL, + + /** + * Indicates that the engine has + * crashed and is in a state + * where further usage is HIGHLY + * discouraged. Any further calls + * may cause the process or + * virtual machine to exit fatally. + * + * This is a final state. The + * engine cannot be initialized + * again after having crashed. * * @since v1-alpha10 */