Overhaul engine init procedure + add new placeholder
This commit is contained in:
parent
4281f946be
commit
c533a06148
8 changed files with 200 additions and 135 deletions
|
@ -32,6 +32,7 @@ import de.staropensource.engine.base.internal.type.DependencySubsystemVector;
|
|||
import de.staropensource.engine.base.logging.PrintStreamService;
|
||||
import de.staropensource.engine.base.logging.*;
|
||||
import de.staropensource.engine.base.logging.backend.async.LoggingQueue;
|
||||
import de.staropensource.engine.base.logging.backend.async.LoggingThread;
|
||||
import de.staropensource.engine.base.type.DependencyVector;
|
||||
import de.staropensource.engine.base.type.EngineState;
|
||||
import de.staropensource.engine.base.type.immutable.ImmutableLinkedList;
|
||||
|
@ -51,7 +52,6 @@ import org.reflections.scanners.Scanners;
|
|||
import org.reflections.util.ClasspathHelper;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -177,33 +177,74 @@ public final class Engine extends SubsystemClass {
|
|||
/**
|
||||
* Initializes the StarOpenSource Engine.
|
||||
*
|
||||
* @throws IllegalStateException when running in an incompatible environment
|
||||
* @since v1-alpha6
|
||||
* @throws RuntimeException for all exceptions thrown by this constructor
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
private Engine() throws RuntimeException {
|
||||
try {
|
||||
instance = this;
|
||||
state = EngineState.EARLY_STARTUP;
|
||||
|
||||
long initTime = Miscellaneous.measureExecutionTime(() -> {
|
||||
try {
|
||||
de.staropensource.engine.base.logging.backend.async.LoggingThread.startThread(false);
|
||||
// For measuring the initialization time
|
||||
long initTimeEarly = System.currentTimeMillis();
|
||||
long initTimeLate = initTimeEarly;
|
||||
|
||||
// Check for incompatible JVM implementations
|
||||
checkJvmIncompatibilities();
|
||||
|
||||
// Display that the engine is initializing
|
||||
Logger.verb("Initializing engine");
|
||||
|
||||
// Start the logging thread
|
||||
Logger.diag("Starting logging infrastructure");
|
||||
LoggingThread.startThread(false);
|
||||
PrintStreamService.initializeStreams();
|
||||
|
||||
// Initialize EngineInternals
|
||||
Logger.diag("Initializing EngineInternals class");
|
||||
new EngineInternals();
|
||||
|
||||
// Load engine configuration
|
||||
Logger.diag("Loading engine configuration");
|
||||
new EngineConfiguration();
|
||||
EngineConfiguration.getInstance().loadConfiguration();
|
||||
|
||||
Logger.info("Initializing engine");
|
||||
initializeClasses(); // Initialize classes
|
||||
if (checkEnvironment()) // Check environment
|
||||
throw new IllegalStateException("Running in an incompatible environment");
|
||||
ensureEnvironment(); // Prepare the environment and ensure safety
|
||||
cacheEvents(); // Cache event listeners
|
||||
// Load engine build information
|
||||
Logger.diag("Loading engine build information");
|
||||
EngineInformation.update();
|
||||
|
||||
// Check for reflective classpath scanning compatibility
|
||||
checkReflectiveClasspathScanningCompatibility();
|
||||
|
||||
// Check for Java version incompatibilities
|
||||
checkJavaVersion();
|
||||
|
||||
// Initialize PlaceholderEngine
|
||||
Logger.diag("Initializing PlaceholderEngine");
|
||||
PlaceholderEngine.initialize();
|
||||
|
||||
// Initialize static FileAccess instances
|
||||
Logger.diag("Initializing static FileAccess instances");
|
||||
FileAccess.initializeInstances();
|
||||
|
||||
// Install the safety shutdown hook
|
||||
Logger.diag("Installing safety shutdown hook");
|
||||
EngineInternals.getInstance().installSafetyShutdownHook(true);
|
||||
|
||||
// Cache events
|
||||
Logger.diag("Caching event listeners");
|
||||
cacheEvents();
|
||||
|
||||
// Complete early initialization stage
|
||||
Logger.verb("Completing early initialization stage");
|
||||
state = EngineState.STARTUP;
|
||||
initTimeEarly = System.currentTimeMillis() - initTimeEarly;
|
||||
|
||||
// Perform automatic subsystem initialization
|
||||
if (EngineConfiguration.getInstance().isInitialPerformSubsystemInitialization()) {
|
||||
collectSubsystems(); // Collect subsystems
|
||||
// Collect all subsystems
|
||||
Logger.diag("Collecting subsystems");
|
||||
collectSubsystems();
|
||||
|
||||
// Initialize subsystems
|
||||
try {
|
||||
|
@ -212,14 +253,28 @@ public final class Engine extends SubsystemClass {
|
|||
Logger.error("Subsystem dependency resolution failed");
|
||||
}
|
||||
}
|
||||
|
||||
// Complete late initialization stage
|
||||
Logger.verb("Completing late initialization stage");
|
||||
state = EngineState.RUNNING;
|
||||
initTimeLate = System.currentTimeMillis() - initTimeLate;
|
||||
|
||||
// Print welcome message
|
||||
Logger.info(
|
||||
"""
|
||||
Welcome to the StarOpenSource Engine "%engine_version_codename%" %engine_version%!
|
||||
Running commit %engine_git_commit_id_long% (dirty %engine_git_dirty%).
|
||||
Initialization took %init_time_total%ms (early %init_time_early%ms, late %init_time_late%ms).
|
||||
|
||||
Copyright (c) 2024 The StarOpenSource Engine Authors
|
||||
Licensed under the GNU Affero General Public License v3"""
|
||||
.replace("%init_time_total%", String.valueOf(initTimeEarly + initTimeLate))
|
||||
.replace("%init_time_early%", String.valueOf(initTimeEarly))
|
||||
.replace("%init_time_late%", String.valueOf(initTimeLate))
|
||||
);
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
});
|
||||
|
||||
Logger.verb("Completing late initialization stage");
|
||||
state = EngineState.RUNNING;
|
||||
Logger.info("Initialized sos!engine %engine_version% (commit %engine_git_commit_id_long%-%engine_git_branch%, dirty %engine_git_dirty%) in " + initTime + "ms\nThe StarOpenSource Engine is licensed under the GNU AGPL v3. Copyright (c) 2024 The StarOpenSource Engine Authors.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,54 +285,32 @@ public final class Engine extends SubsystemClass {
|
|||
* @throws RuntimeException on engine initialization failure
|
||||
* @since v1-alpha6
|
||||
*/
|
||||
public static void initialize() throws IllegalStateException, RuntimeException {
|
||||
public static void initialize() throws RuntimeException {
|
||||
try {
|
||||
if (instance == null)
|
||||
new Engine();
|
||||
} catch (RuntimeException exception) {
|
||||
if (exception.getCause() instanceof IllegalStateException)
|
||||
throw (IllegalStateException) exception.getCause();
|
||||
else {
|
||||
Logger.error("Engine initialization failed");
|
||||
Logger.error(Miscellaneous.getStackTraceHeader(exception.getCause()));
|
||||
for (String line : Miscellaneous.getStackTraceAsString(exception.getCause(), true).split("\n"))
|
||||
Logger.error(line);
|
||||
|
||||
throw new RuntimeException("Engine initialization failed", exception.getCause());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes all classes.
|
||||
* Checks if the running JVM implementation is not supported by the engine.
|
||||
*
|
||||
* @since v1-alpha0
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
private void initializeClasses() throws IOException {
|
||||
Logger.verb("Initializing engine classes");
|
||||
|
||||
// Initialize essential engine classes
|
||||
new EngineInternals();
|
||||
EngineInformation.update();
|
||||
PlaceholderEngine.initialize();
|
||||
|
||||
// Non-essential engine classes
|
||||
PrintStreamService.initializeStreams();
|
||||
FileAccess.initializeInstances();
|
||||
private void checkJvmIncompatibilities() {
|
||||
if (System.getProperties().getProperty("sosengine.base.allowUnsupportedJVMInitialization", "false").equals("true")) {
|
||||
Logger.warn("Skipping JVM implementation incompatibilities check");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the environment is compatible with the engine build.
|
||||
*
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
private boolean checkEnvironment() {
|
||||
Logger.diag("Checking environment");
|
||||
|
||||
// Warn about potential Java incompatibilities
|
||||
if (JvmInformation.getJavaVersion() > EngineInformation.getJavaSource())
|
||||
Logger.warn("The StarOpenSource Engine is running on an untested Java version.\nThings may not work as expected or features which can improve performance, stability, compatibility or ease of use may be missing.\nIf you encounter issues, try running a JVM implementing Java " + EngineInformation.getJavaSource());
|
||||
|
||||
// Shutdown if running in an unsupported JVM
|
||||
// Substrate VM (GraalVM Community)
|
||||
if (JvmInformation.getImplementationName().equals("Substrate VM") && JvmInformation.getImplementationVendor().equals("GraalVM Community")) {
|
||||
Logger.error("##############################################################################################");
|
||||
Logger.error("## Running in Substrate VM, which is the name of the JVM used by GraalVM native-image. ##");
|
||||
|
@ -293,37 +326,33 @@ public final class Engine extends SubsystemClass {
|
|||
Logger.error("##############################################################################################");
|
||||
Runtime.getRuntime().exit(255);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if reflective classpath scanning is supported.
|
||||
*
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
private void checkReflectiveClasspathScanningCompatibility() {
|
||||
// Check if reflective classpath scanning is supported
|
||||
if (checkClasspathScanningSupport()) {
|
||||
Logger.warn("Running in an classpath scanning-unfriendly environment, disabling.");
|
||||
if (System.getProperties().getProperty("sosengine.base.considerEnvironmentUnfriendlyToClasspathScanning", "false").equals("true")) {
|
||||
Logger.warn("Running in an classpath scanning-unfriendly environment, disabling classpath scanning support.");
|
||||
Logger.warn("If shit doesn't work and is expected to be discovered by annotations, you'll need to");
|
||||
Logger.warn("either register it first or have to place classes in some package.");
|
||||
Logger.warn("either register it first or have to update some engine configuration setting.");
|
||||
Logger.warn("Please consult sos!engine's documentation for more information about this issue.");
|
||||
EngineInternals.getInstance().overrideReflectiveClasspathScanning(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether scanning the classpath is supported.
|
||||
* Checks and warns if the Java version of the
|
||||
* running JVM is higher than the engine supports.
|
||||
*
|
||||
* @return test results
|
||||
* @since v1-alpha5
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
private boolean checkClasspathScanningSupport() {
|
||||
// This may be expanded in the future
|
||||
return EngineConfiguration.getInstance().isInitialForceDisableClasspathScanning();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the execution safety of the environment.
|
||||
*
|
||||
* @since v1-alpha4
|
||||
*/
|
||||
private void ensureEnvironment() {
|
||||
EngineInternals.getInstance().installSafetyShutdownHook(true);
|
||||
private void checkJavaVersion() {
|
||||
if (JvmInformation.getJavaVersion() > EngineInformation.getJavaSource())
|
||||
Logger.warn("The StarOpenSource Engine is running on an untested Java version.\nThings may not work as expected or features which can improve performance, stability, compatibility or ease of use may be missing.\nIf you encounter issues, try running a JVM implementing Java " + EngineInformation.getJavaSource());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -332,15 +361,10 @@ public final class Engine extends SubsystemClass {
|
|||
* @since v1-alpha0
|
||||
*/
|
||||
private void cacheEvents() {
|
||||
Logger.diag("Caching events");
|
||||
|
||||
// Internal events
|
||||
EventHelper.cacheEvent(InternalEngineShutdownEvent.class);
|
||||
|
||||
// General events
|
||||
EventHelper.cacheEvent(EngineCrashEvent.class);
|
||||
EventHelper.cacheEvent(EngineShutdownEvent.class);
|
||||
EventHelper.cacheEvent(EngineSoftCrashEvent.class);
|
||||
EventHelper.cacheEvent(InternalEngineShutdownEvent.class);
|
||||
EventHelper.cacheEvent(LogEvent.class);
|
||||
EventHelper.cacheEvent(ThrowableCatchEvent.class);
|
||||
}
|
||||
|
@ -427,7 +451,7 @@ public final class Engine extends SubsystemClass {
|
|||
resolver.addVectors(subsystems);
|
||||
|
||||
// Resolve dependencies and get order
|
||||
Logger.verb("Resolving subsystem dependencies");
|
||||
Logger.diag("Resolving subsystem dependencies");
|
||||
try {
|
||||
for (DependencyVector vector : resolver.resolve().getOrder()) // smol workaround
|
||||
order.add((DependencySubsystemVector) vector);
|
||||
|
@ -450,7 +474,7 @@ public final class Engine extends SubsystemClass {
|
|||
}
|
||||
|
||||
// Initialize subsystems
|
||||
Logger.verb("Initializing engine subsystems");
|
||||
Logger.diag("Initializing engine subsystems");
|
||||
long initTime;
|
||||
for (DependencySubsystemVector vector : subsystems) {
|
||||
Logger.diag("Initializing subsystem '" + vector.getSubsystemClass().getName() + "' (" + vector.getSubsystemClass().getClass().getName() + ")");
|
||||
|
|
|
@ -128,21 +128,6 @@ public final class EngineConfiguration extends Configuration {
|
|||
*/
|
||||
private boolean initialPerformSubsystemInitialization;
|
||||
|
||||
/**
|
||||
* If enabled, will force-disable reflective classpath scanning.
|
||||
*
|
||||
* @see EngineInternals#getReflectiveClasspathScanning()
|
||||
* @see EngineInternals#overrideReflectiveClasspathScanning(boolean)
|
||||
* @since v1-alpha5
|
||||
* -- GETTER --
|
||||
* Gets the value for {@link #initialForceDisableClasspathScanning}.
|
||||
*
|
||||
* @return variable value
|
||||
* @see #initialForceDisableClasspathScanning
|
||||
* @since v1-alpha5
|
||||
*/
|
||||
private boolean initialForceDisableClasspathScanning;
|
||||
|
||||
/**
|
||||
* Will try to load the specified classes as subsystems,
|
||||
* if reflective classpath scanning is disabled.
|
||||
|
@ -352,7 +337,6 @@ public final class EngineConfiguration extends Configuration {
|
|||
case "debugEvents" -> debugEvents = parser.getBoolean(group + property);
|
||||
|
||||
case "initialPerformSubsystemInitialization" -> initialPerformSubsystemInitialization = parser.getBoolean(group + property);
|
||||
case "initialForceDisableClasspathScanning" -> initialForceDisableClasspathScanning = parser.getBoolean(group + property);
|
||||
case "initialIncludeSubsystemClasses" -> {
|
||||
initialIncludeSubsystemClasses = new HashSet<>();
|
||||
initialIncludeSubsystemClasses.addAll(Arrays.stream(parser.getString(group + property).split(",")).toList());
|
||||
|
@ -374,7 +358,7 @@ public final class EngineConfiguration extends Configuration {
|
|||
try {
|
||||
logLevel = LogLevel.valueOf(parser.getString(group + property).toUpperCase());
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
Logger.error("The log level " + parser.getString(group + property) + " is not valid");
|
||||
Logger.error("The log level '" + parser.getString(group + property) + "' is not valid");
|
||||
}
|
||||
}
|
||||
case "logFeatures" -> logFeatures = Set.copyOf(Arrays.stream(parser.getString(group + property).split(",")).toList());
|
||||
|
@ -403,7 +387,6 @@ public final class EngineConfiguration extends Configuration {
|
|||
debugEvents = false;
|
||||
|
||||
initialPerformSubsystemInitialization = true;
|
||||
initialForceDisableClasspathScanning = false;
|
||||
initialIncludeSubsystemClasses = new HashSet<>();
|
||||
|
||||
errorShortcodeParser = true;
|
||||
|
@ -428,7 +411,6 @@ public final class EngineConfiguration extends Configuration {
|
|||
case "debugEvents" -> debugEvents;
|
||||
|
||||
case "initialPerformSubsystemInitialization" -> initialPerformSubsystemInitialization;
|
||||
case "initialForceDisableClasspathScanning" -> initialForceDisableClasspathScanning;
|
||||
case "initialIncludeSubsystemClasses" -> initialIncludeSubsystemClasses;
|
||||
|
||||
case "errorShortcodeParser" -> errorShortcodeParser;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* STAROPENSOURCE ENGINE SOURCE FILE
|
||||
* Copyright (c) 2024 The StarOpenSource Engine Authors
|
||||
* Licensed under the GNU Affero General Public License v3
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.staropensource.engine.base.internal.implementation.placeholder;
|
||||
|
||||
import de.staropensource.engine.base.implementable.Placeholder;
|
||||
import de.staropensource.engine.base.utility.information.EngineInformation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Implements the {@code engine_version_codename} placeholder.
|
||||
*
|
||||
* @see Placeholder
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
@SuppressWarnings({ "unused" })
|
||||
public final class EngineVersionCodename implements Placeholder {
|
||||
/**
|
||||
* Creates and initializes an instance of this event.
|
||||
*
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
public EngineVersionCodename() {}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public @NotNull String replace(@NotNull String text) {
|
||||
return text.replace("%engine_version_codename%", EngineInformation.getVersioningCodename());
|
||||
}
|
||||
}
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package de.staropensource.engine.base.logging;
|
||||
|
||||
import de.staropensource.engine.base.Engine;
|
||||
import de.staropensource.engine.base.type.EngineState;
|
||||
import de.staropensource.engine.base.type.logging.LogLevel;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -164,18 +166,14 @@ public final class PrintStreamService {
|
|||
|
||||
/**
|
||||
* Initializes all {@link PrintStream}s offered by this class.
|
||||
* <p>
|
||||
* Only works during early engine startup.
|
||||
*
|
||||
* @since v1-alpha4
|
||||
* @since v1-alpha8
|
||||
*/
|
||||
public static void initializeStreams() {
|
||||
// Close all existing streams
|
||||
if (diag != null) diag.close();
|
||||
if (verb != null) verb.close();
|
||||
if (sarn != null) sarn.close();
|
||||
if (info != null) info.close();
|
||||
if (warn != null) warn.close();
|
||||
if (error != null) error.close();
|
||||
if (crash != null) crash.close();
|
||||
if (Engine.getInstance() == null || Engine.getInstance().getState() != EngineState.EARLY_STARTUP)
|
||||
return;
|
||||
|
||||
// Create streams
|
||||
diag = LogStream.createPrintStream(LogLevel.DIAGNOSTIC);
|
||||
|
|
|
@ -222,10 +222,6 @@ public final class CrashHandler {
|
|||
.append(EngineConfiguration.getInstance().isInitialPerformSubsystemInitialization())
|
||||
.append("'\n")
|
||||
|
||||
.append("EngineConfiguration#initialForceDisableClasspathScanning='")
|
||||
.append(EngineConfiguration.getInstance().isInitialForceDisableClasspathScanning())
|
||||
.append("'\n")
|
||||
|
||||
.append("EngineConfiguration#initialIncludeSubsystemClasses='")
|
||||
.append(EngineConfiguration.getInstance().getInitialIncludeSubsystemClasses())
|
||||
.append("'\n")
|
||||
|
|
|
@ -53,7 +53,7 @@ public final class Processor {
|
|||
* @since v1-alpha8
|
||||
*/
|
||||
public static boolean isFeatureEnabled(@NotNull String feature) {
|
||||
return EngineConfiguration.getInstance().getLogFeatures().contains(feature);
|
||||
return EngineConfiguration.getInstance() != null && EngineConfiguration.getInstance().getLogFeatures().contains(feature);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,7 +66,7 @@ public final class Processor {
|
|||
* @since v1-alpha8
|
||||
*/
|
||||
public static void handle(@NotNull LogLevel level, @NotNull StackTraceElement issuer, @NotNull String message) {
|
||||
if (EngineConfiguration.getInstance().isOptimizeLogging())
|
||||
if (EngineConfiguration.getInstance() != null && EngineConfiguration.getInstance().isOptimizeLogging())
|
||||
LoggingQueue.add(level, issuer, message);
|
||||
else
|
||||
process(level, issuer, message);
|
||||
|
@ -84,7 +84,18 @@ public final class Processor {
|
|||
StringBuilder output = new StringBuilder();
|
||||
|
||||
// Filter out
|
||||
if (level.compareTo(EngineConfiguration.getInstance().getLogLevel()) < 0)
|
||||
if (EngineConfiguration.getInstance() == null) {
|
||||
LogLevel maxLevel = LogLevel.INFORMATIONAL;
|
||||
|
||||
try {
|
||||
maxLevel = LogLevel.valueOf(System.getProperties().getProperty("sosengine.base.logLevel", "informational").toUpperCase());
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
Logger.error("The log level '" + System.getProperties().getProperty("sosengine.base.logLevel", "informational") + "' is not valid");
|
||||
}
|
||||
|
||||
if (level.compareTo(maxLevel) < 0)
|
||||
return;
|
||||
} else if (level.compareTo(EngineConfiguration.getInstance().getLogLevel()) < 0)
|
||||
return;
|
||||
|
||||
for (String classNameDisallowed : Filterer.disallowedClasses)
|
||||
|
|
|
@ -44,18 +44,25 @@ public final class LoggingThread {
|
|||
* @since v1-alpha8
|
||||
*/
|
||||
private static final @NotNull Runnable threadCode = () -> {
|
||||
int pollingSpeed;
|
||||
|
||||
while (!(
|
||||
Thread.currentThread().isInterrupted()
|
||||
|| !(EngineConfiguration.getInstance() == null || EngineConfiguration.getInstance().isOptimizeLogging())
|
||||
|| Engine.getInstance().getState() == EngineState.SHUTDOWN
|
||||
|| Engine.getInstance().getState() == EngineState.CRASHED
|
||||
)) {
|
||||
if (EngineConfiguration.getInstance() == null)
|
||||
pollingSpeed = 5;
|
||||
else
|
||||
pollingSpeed = EngineConfiguration.getInstance().getLogPollingSpeed();
|
||||
|
||||
// Flush all log messages
|
||||
LoggingQueue.flush();
|
||||
|
||||
// Sleep for whatever has been configured
|
||||
if (EngineConfiguration.getInstance().getLogPollingSpeed() > 0) {
|
||||
long sleepDuration = System.currentTimeMillis() + EngineConfiguration.getInstance().getLogPollingSpeed();
|
||||
if (pollingSpeed > 0) {
|
||||
long sleepDuration = System.currentTimeMillis() + pollingSpeed;
|
||||
while (System.currentTimeMillis() < sleepDuration)
|
||||
Thread.onSpinWait();
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ public final class PlaceholderEngine {
|
|||
placeholders.add(new EngineGitDirty());
|
||||
// engine_version*
|
||||
placeholders.add(new EngineVersion());
|
||||
placeholders.add(new EngineVersionCodename());
|
||||
placeholders.add(new EngineVersionVersion());
|
||||
placeholders.add(new EngineVersionType());
|
||||
placeholders.add(new EngineVersionTyperelease());
|
||||
|
|
Loading…
Reference in a new issue