UNPKG

@freemework/hosting

Version:

Hosting library of the Freemework Project.

186 lines 8.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.flauncher = flauncher; exports.defaultConfigurationLoader = defaultConfigurationLoader; exports.registerShutdownHook = registerShutdownHook; const common_1 = require("@freemework/common"); const index_js_1 = require("../configuration/index.js"); const f_launcher_exception_js_1 = require("./f_launcher_exception.js"); const f_launcher_restart_required_exception_js_1 = require("./f_launcher_restart_required_exception.js"); function flauncher(...args) { const log = common_1.FLogger.create("FLauncher"); const cancellationTokenSource = new common_1.FCancellationTokenSourceManual(); const executionContext = new common_1.FCancellationExecutionContext(common_1.FExecutionContext.Empty, cancellationTokenSource.token); async function run() { process.on("unhandledRejection", (e) => { const ex = common_1.FException.wrapIfNeeded(e); log.debug(executionContext, "Unhandled Rejection", ex); log.fatal(executionContext, `Unhandled Rejection. ${ex.constructor.name}: ${ex.message}`); fireShutdownHooks().finally(function () { process.exit(255); }); }); let destroyRequestCount = 0; const shutdownSignals = ["SIGTERM", "SIGINT"]; let runtimeStuff; if (args.length === 3 && typeof args[0] === "function" && typeof args[1] === "function") { runtimeStuff = Object.freeze({ loader: args[0], parser: args[1], runtimeFactory: args[2], }); } else if (args.length === 2 && typeof args[0] === "function" && typeof args[1] === "function") { runtimeStuff = Object.freeze({ loader: defaultConfigurationLoader, parser: args[0], runtimeFactory: args[1], }); } else if (args.length === 1 && typeof args[0] === "function") { runtimeStuff = Object.freeze({ parser: null, runtimeFactory: args[0], }); } else { throw new Error("Wrong arguments"); } let runtime; if (runtimeStuff.parser === null) { runtime = await runtimeStuff.runtimeFactory(executionContext); } else { const rawConfiguration = await runtimeStuff.loader(executionContext); const parsedConfiguration = runtimeStuff.parser(rawConfiguration); runtime = await runtimeStuff.runtimeFactory(executionContext, parsedConfiguration); } shutdownSignals.forEach((signal) => process.on(signal, () => gracefulShutdown(signal))); async function gracefulShutdown(signal) { if (destroyRequestCount++ === 0) { cancellationTokenSource.cancel(); if (log.isInfoEnabled) { log.info(executionContext, `Interrupt signal received: ${signal}`); } try { await runtime.dispose(); } catch (e) { const ex = common_1.FException.wrapIfNeeded(e); const msg = "Unexpected exception from the dispose() method of your runtime object."; log.debug(executionContext, msg, ex); log.error(executionContext, () => `${msg} ${ex.message}`); } await fireShutdownHooks(); process.exit(0); } else { if (log.isInfoEnabled) { log.info(executionContext, `Interrupt signal (${destroyRequestCount}) received: ${signal}`); } } } } log.info(executionContext, "Starting application..."); run() .then(() => { if (log.isInfoEnabled) { log.info(executionContext, `Application was started. Process ID: ${process.pid}`); } }) .catch((e) => { const ex = common_1.FException.wrapIfNeeded(e); if (ex instanceof common_1.FCancellationException) { log.warn(executionContext, "Runtime initialization was cancelled by user"); fireShutdownHooks().finally(function () { process.exit(0); }); } if (log.isFatalEnabled) { if (e instanceof f_launcher_exception_js_1.FLauncherException) { log.fatal(executionContext, `Runtime initialization failed with ${e.constructor.name}: ${e.message}`); } else { log.fatal(executionContext, `Runtime initialization failed with error: ${ex.message}`); log.debug(executionContext, ex.message, ex); } } const exitCode = ex instanceof f_launcher_restart_required_exception_js_1.FLauncherRestartRequiredException ? ex.exitCode : 127; if (process.env["NODE_ENV"] === "development") { setTimeout(() => { fireShutdownHooks().finally(function () { process.exit(exitCode); }); }, 1000); } else { fireShutdownHooks().finally(function () { process.exit(exitCode); }); } }); } async function defaultConfigurationLoader(_executionContext) { const chainItems = []; for (const arg of process.argv) { if (arg.startsWith(defaultConfigurationLoader.CONFIG_FILE_ARG)) { const configFile = arg.substring(defaultConfigurationLoader.CONFIG_FILE_ARG.length); const fileConf = await index_js_1.FConfigurationProperties.fromFile(configFile); chainItems.push(fileConf); } else if (arg.startsWith(defaultConfigurationLoader.CONFIG_TOML_FILE_ARG)) { const configFile = arg.substring(defaultConfigurationLoader.CONFIG_TOML_FILE_ARG.length); const fileConf = await index_js_1.FConfigurationToml.fromFile(configFile); chainItems.push(fileConf); } else if (arg.startsWith(defaultConfigurationLoader.CONFIG_SECRET_DIR_ARG)) { const secretsDir = arg.substring(defaultConfigurationLoader.CONFIG_SECRET_DIR_ARG.length); const secretsConfiguration = await index_js_1.FConfigurationDirectory.read(secretsDir); chainItems.push(secretsConfiguration); } else if (arg === defaultConfigurationLoader.CONFIG_ENV_ARG) { const envConf = new index_js_1.FConfigurationEnv(); chainItems.push(envConf); } } if (chainItems.length === 0) { throw new f_launcher_exception_js_1.FLauncherException("Missing configuration. Please provide at least one of: " + `${defaultConfigurationLoader.CONFIG_ENV_ARG}, ${defaultConfigurationLoader.CONFIG_FILE_ARG}, ${defaultConfigurationLoader.CONFIG_TOML_FILE_ARG}, ${defaultConfigurationLoader.CONFIG_SECRET_DIR_ARG}`); } chainItems.reverse(); const rawConfiguration = new common_1.FConfigurationChain(...chainItems); return rawConfiguration; } (function (defaultConfigurationLoader) { defaultConfigurationLoader.CONFIG_ENV_ARG = "--config-env"; defaultConfigurationLoader.CONFIG_FILE_ARG = "--config-file="; defaultConfigurationLoader.CONFIG_TOML_FILE_ARG = "--config-toml-file="; defaultConfigurationLoader.CONFIG_SECRET_DIR_ARG = "--config-secrets-dir="; })(defaultConfigurationLoader || (exports.defaultConfigurationLoader = defaultConfigurationLoader = {})); function registerShutdownHook(cb) { shutdownHooks.push(cb); } const shutdownHooks = []; async function fireShutdownHooks() { if (shutdownHooks.length > 0) { const log = common_1.FLogger.create("FLauncher.fireShutdownHooks"); log.debug(common_1.FExecutionContext.Empty, "Executing shutdown hooks..."); const shutdownHooksCopy = [...shutdownHooks]; do { const cb = shutdownHooksCopy.pop(); try { await cb(); } catch (e) { const ex = common_1.FException.wrapIfNeeded(e); log.warn(common_1.FExecutionContext.Empty, `An shutdown hook was finished with error: ${ex.message}`); log.debug(common_1.FExecutionContext.Empty, "An shutdown hook was finished with error", ex); } } while (shutdownHooksCopy.length > 0); } } //# sourceMappingURL=f_launcher.js.map