diff --git a/Project.njsproj b/Project.njsproj
index 2c9ca85ab..b286cdfa9 100644
--- a/Project.njsproj
+++ b/Project.njsproj
@@ -47,6 +47,9 @@
Code
+
+ Code
+
Code
diff --git a/Root.js b/Root.js
index ef5e0b714..3f85db528 100644
--- a/Root.js
+++ b/Root.js
@@ -149,6 +149,7 @@
const TRADING_BOT_MAIN_LOOP_MODULE = require('./TradingBotProcessMainLoop');
const INDICATOR_BOT_MAIN_LOOP_MODULE = require('./IndicatorBotProcessMainLoop');
const EXTRACTION_BOT_MAIN_LOOP_MODULE = require('./SensorBotProcessMainLoop');
+ const TRADING_ENGINE_MAIN_LOOP_MODULE = require('./TradingEngineProcessMainLoop');
/* Loop through all the processes configured to be run by this Node.js Instance. */
@@ -353,6 +354,10 @@
runIndicatorBot(botConfig, processConfig, month, year);
break;
}
+ case 'Trading-Engine': {
+ runTradingEngine(botConfig, processConfig);
+ break;
+ }
default: {
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> Unexpected bot type. -> botConfig.type = " + botConfig.type);
}
@@ -546,74 +551,6 @@
}
}
- function runIndicatorBot(pBotConfig, pProcessConfig, pMonth, pYear) {
-
- try {
- const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
- let logger;
-
- logger = DEBUG_MODULE.newDebugLog();
- logger.bot = pBotConfig;
-
- if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> Entering function."); }
- if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pMonth = " + pMonth); }
- if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pYear = " + pYear); }
-
- let indicatorBotMainLoop = INDICATOR_BOT_MAIN_LOOP_MODULE.newIndicatorBotProcessMainLoop(pBotConfig, logger);
- indicatorBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady);
-
- function onInitializeReady(err) {
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
-
- indicatorBotMainLoop.run(pMonth, pYear, whenRunFinishes);
-
- function whenRunFinishes(err) {
-
- pBotConfig.loopCounter = 0;
-
- let botId;
- if (pYear !== undefined) {
- botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process + "." + pYear + "." + pMonth;
- } else {
- botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process;
- }
-
- if (err.result === global.DEFAULT_OK_RESPONSE.result) {
-
- logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
- logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
-
- console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
- console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
-
- logger.persist();
-
- } else {
-
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = ", err);
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
- console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
- logger.persist();
- }
- }
-
- } else {
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = ", err);
- logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> Failed to initialize the bot. ");
- console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = ", err);
- logger.persist();
- }
- }
- }
- catch (err) {
- console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> err = ", err);
-
- }
- }
-
function runTradingBot(pBotConfig, pProcessConfig) {
try {
@@ -792,6 +729,137 @@
}
}
+ function runIndicatorBot(pBotConfig, pProcessConfig, pMonth, pYear) {
+
+ try {
+ const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
+ let logger;
+
+ logger = DEBUG_MODULE.newDebugLog();
+ logger.bot = pBotConfig;
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> Entering function."); }
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pMonth = " + pMonth); }
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> pYear = " + pYear); }
+
+ let indicatorBotMainLoop = INDICATOR_BOT_MAIN_LOOP_MODULE.newIndicatorBotProcessMainLoop(pBotConfig, logger);
+ indicatorBotMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady);
+
+ function onInitializeReady(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ indicatorBotMainLoop.run(pMonth, pYear, whenRunFinishes);
+
+ function whenRunFinishes(err) {
+
+ pBotConfig.loopCounter = 0;
+
+ let botId;
+ if (pYear !== undefined) {
+ botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process + "." + pYear + "." + pMonth;
+ } else {
+ botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process;
+ }
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+
+ logger.persist();
+
+ } else {
+
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> err = ", err);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bye.");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
+ logger.persist();
+ }
+ }
+
+ } else {
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = ", err);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> Failed to initialize the bot. ");
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> onInitializeReady -> err = ", err);
+ logger.persist();
+ }
+ }
+ }
+ catch (err) {
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runIndicatorBot -> err = ", err);
+
+ }
+ }
+
+ function runTradingEngine(pBotConfig, pProcessConfig) {
+
+ try {
+ const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
+ let logger;
+
+ logger = DEBUG_MODULE.newDebugLog();
+ logger.bot = pBotConfig;
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> Entering function."); }
+
+ let tradingEngineMainLoop = TRADING_ENGINE_MAIN_LOOP_MODULE.newTradingEngineProcessMainLoop(pBotConfig, logger);
+ tradingEngineMainLoop.initialize(UI_COMMANDS, pProcessConfig, onInitializeReady);
+
+ function onInitializeReady(err) {
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ tradingEngineMainLoop.run(whenRunFinishes);
+
+ function whenRunFinishes(err) {
+
+ pBotConfig.loopCounter = 0;
+
+ let botId;
+
+ botId = pBotConfig.devTeam + "." + pBotConfig.codeName + "." + pBotConfig.process;
+
+ if (err.result === global.DEFAULT_OK_RESPONSE.result) {
+
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+ logger.write(MODULE_NAME, "[INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> botId = " + botId);
+ console.log(logDisplace + "Root : [INFO] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished sucessfully.");
+
+ logger.persist();
+
+ } else {
+
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> err = ", err);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Execution will be stopped. ");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bye.");
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot Id = " + botId);
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> whenStartFinishes -> Bot execution finished with errors. Please check the logs.");
+ logger.persist();
+ }
+ }
+
+ } else {
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = ", err);
+ logger.write(MODULE_NAME, "[ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> Failed to initialize the bot. ");
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> onInitializeReady -> err = ", err);
+ logger.persist();
+ }
+ }
+ }
+ catch (err) {
+ console.log(logDisplace + "Root : [ERROR] start -> findProcess -> runTradingEngine -> err = ", err);
+
+ }
+ }
+
}
catch (err) {
console.log(logDisplace + "Root : [ERROR] start -> findProcess -> err.message = " + err.message);
diff --git a/TradingEngineProcessMainLoop.js b/TradingEngineProcessMainLoop.js
new file mode 100644
index 000000000..d20e893b9
--- /dev/null
+++ b/TradingEngineProcessMainLoop.js
@@ -0,0 +1,928 @@
+exports.newTradingEngineProcessMainLoop = function newTradingEngineProcessMainLoop(bot, parentLogger) {
+
+ const ROOT_DIR = './';
+
+ const MODULE_NAME = "Trading Engine Process Main Loop";
+ const FULL_LOG = true;
+
+ let USER_BOT_MODULE;
+ let COMMONS_MODULE;
+
+ const MULTI_PERIOD_MARKET = require(ROOT_DIR + 'MultiPeriodMarket');
+ const MULTI_PERIOD_DAILY = require(ROOT_DIR + 'MultiPeriodDaily');
+ const FILE_STORAGE = require('./Integrations/FileStorage.js');
+ let fileStorage = FILE_STORAGE.newFileStorage();
+
+ const DEBUG_MODULE = require(ROOT_DIR + 'DebugLog');
+ let logger; // We need this here in order for the loopHealth function to work and be able to rescue the loop when it gets in trouble.
+
+ let nextLoopTimeoutHandle;
+ let checkLoopHealthHandle;
+
+ let thisObject = {
+ initialize: initialize,
+ run: run
+ };
+
+ let processConfig;
+ let UI_COMMANDS;
+
+ return thisObject;
+
+ function initialize(pUI_COMMANDS, pProcessConfig, callBackFunction) {
+
+ /* This function is exactly the same in the 3 modules representing the 2 different bot types loops. */
+
+ try {
+ if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] initialize -> Entering function."); }
+
+ UI_COMMANDS = pUI_COMMANDS;
+ processConfig = pProcessConfig;
+
+ let filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo + "/" + pProcessConfig.name
+ filePath += "/User.Bot.js"
+
+ fileStorage.getTextFile(global.DEV_TEAM, filePath, onBotDownloaded);
+
+ function onBotDownloaded(err, text) {
+
+ if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
+
+ parentLogger.write(MODULE_NAME, "[ERROR] initialize -> onInizialized -> onBotDownloaded -> err.message = " + err.message);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+
+ USER_BOT_MODULE = {}
+ USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function
+
+ filePath = global.DEV_TEAM + "/" + "bots" + "/" + bot.repo;
+ filePath += "/Commons.js"
+
+ fileStorage.getTextFile(global.DEV_TEAM, filePath, onCommonsDownloaded);
+
+ function onCommonsDownloaded(err, text) {
+
+ if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
+ parentLogger.write(MODULE_NAME, "[WARN] initialize -> onBotDownloaded -> onCommonsDownloaded -> Commons not found: " + err.code || err.message);
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ COMMONS_MODULE = {}
+ COMMONS_MODULE.newCommons = eval(text); // TODO This needs to be changed function
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ }
+ }
+ } catch (err) {
+ parentLogger.write(MODULE_NAME, "[ERROR] initialize -> err = ", err);
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+
+ function run(callBackFunction) {
+
+ try {
+
+ if (FULL_LOG === true) { parentLogger.write(MODULE_NAME, "[INFO] run -> Entering function."); }
+
+ bot.enableCheckLoopHealth = true;
+
+ let fixedTimeLoopIntervalHandle;
+
+ if (bot.runAtFixedInterval === true) {
+
+ fixedTimeLoopIntervalHandle = setInterval(loop, bot.fixedInterval);
+
+ } else {
+
+ loop();
+
+ }
+
+ function loop() {
+
+ try {
+
+ function pad(str, max) {
+ str = str.toString();
+ return str.length < max ? pad(" " + str, max) : str;
+ }
+
+ /* For each loop we want to create a new log file. */
+
+ logger = DEBUG_MODULE.newDebugLog();
+ logger.bot = bot;
+ logger.initialize();
+
+ bot.loopCounter++;
+ bot.loopStartTime = new Date().valueOf();
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> Entering function."); }
+
+ /* We define here all the modules that the rest of the infraestructure, including the bots themselves can consume. */
+
+ const UTILITIES = require(ROOT_DIR + 'CloudUtilities');
+ const STATUS_REPORT = require(ROOT_DIR + 'StatusReport');
+ const STATUS_DEPENDENCIES = require(ROOT_DIR + 'StatusDependencies');
+ const DATA_DEPENDENCIES = require(ROOT_DIR + 'DataDependencies');
+ const DATA_SET = require(ROOT_DIR + 'DataSet');
+
+ /* We define the datetime for the process that we are running now. This will be the official processing time for both the infraestructure and the bot. */
+
+ bot.processDatetime = new Date(); // This will be considered the process date and time, so as to have it consistenly all over the execution.
+
+ /* High level log entry */
+
+ console.log(new Date().toISOString() + " " + pad(bot.codeName, 20) + " " + pad(bot.process, 30)
+ + " Entered into Main Loop # " + pad(Number(bot.loopCounter), 8));
+
+ /* We will prepare first the infraestructure needed for the bot to run. There are 3 modules we need to sucessfullly initialize first. */
+
+ let userBot;
+ let processFramework;
+ let statusDependencies;
+ let dataDependencies;
+
+ let nextWaitTime;
+
+ initializeStatusDependencies();
+
+ function initializeStatusDependencies() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> Entering function."); }
+
+ statusDependencies = STATUS_DEPENDENCIES.newStatusDependencies(bot, logger, STATUS_REPORT, UTILITIES);
+
+ statusDependencies.initialize(processConfig.statusDependencies, undefined, undefined, onInizialized);
+
+ function onInizialized(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> onInizialized -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeStatusDependencies -> onInizialized -> Execution finished well.");
+ initializeDataDependencies();
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Operation Failed. Aborting the process.");
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> onInizialized -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeStatusDependencies -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function initializeDataDependencies() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> Entering function."); }
+
+ dataDependencies = DATA_DEPENDENCIES.newDataDependencies(bot, logger, DATA_SET);
+
+ dataDependencies.initialize(processConfig.dataDependencies, onInizialized);
+
+ function onInizialized(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeDataDependencies -> onInizialized -> Execution finished well."); }
+
+ /* If the process is configured to run inside a framework, we continue there, otherwise we run the bot directly. */
+ if (processConfig.framework === undefined) {
+ initializeUserBot();
+ return;
+ }
+
+ switch (processConfig.framework.name) {
+ case 'Multi-Period-Market': {
+ processFramework = MULTI_PERIOD_MARKET.newMultiPeriodMarket(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
+ intitializeProcessFramework();
+ break;
+ }
+ case 'Multi-Period-Daily': {
+ processFramework = MULTI_PERIOD_DAILY.newMultiPeriodDaily(bot, logger, COMMONS_MODULE, UTILITIES, USER_BOT_MODULE, COMMONS_MODULE);
+ intitializeProcessFramework();
+ break;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Process Framework not Supported.");
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Process Framework Name = " + processConfig.framework.name);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ }
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Operation Failed. Aborting the process.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> onInizialized -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeDataDependencies -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function initializeUserBot() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> Entering function."); }
+
+ usertBot = USER_BOT_MODULE.newUserBot(bot, logger, COMMONS_MODULE, UTILITIES, fileStorage);
+
+ usertBot.initialize(statusDependencies, undefined, undefined, onInizialized);
+
+ function onInizialized(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> onInizialized -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write(MODULE_NAME, "[INFO] run -> loop -> initializeUserBot -> onInizialized -> Execution finished well.");
+ startUserBot();
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Operation Failed. Aborting the process.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ case global.CUSTOM_OK_RESPONSE.result: {
+
+ switch (err.message) {
+ case "Too far in the future.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeUserBot -> onInizialized > Too far in the future. This Loop will enter in coma.");
+ nextWaitTime = 'Coma';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Not needed now, but soon.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> initializeUserBot -> onInizialized > Not needed now, but soon. This Loop will continue with Normal wait time.");
+ nextWaitTime = 'Normal';
+ loopControl(nextWaitTime);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized > Unhandled custom response received. -> err.message = " + err.message);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> onInizialized -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> initializeUserBot -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function startUserBot() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> Entering function."); }
+
+ usertBot.start(onFinished);
+
+ function onFinished(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write(MODULE_NAME, "[INFO] run -> loop -> startUserBot -> onFinished -> Execution finished well.");
+ nextWaitTime = 'Normal';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Operation Failed. Aborting the process.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ case global.CUSTOM_OK_RESPONSE.result: {
+
+ switch (err.message) {
+ case "Dependency does not exist.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startUserBot -> onFinished -> Dependency does not exist. This Loop will go to sleep.");
+ nextWaitTime = 'Sleep';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Dependency not ready.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startUserBot -> onFinished -> Dependency not ready. This Loop will go to sleep.");
+ nextWaitTime = 'Sleep';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Month before it is needed.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startUserBot -> onFinished -> Month before it is needed. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ case "Month fully processed.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startUserBot -> onFinished -> Month fully processed. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ case "End of the month reached.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startUserBot -> onFinished -> End of the month reached. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled custom response received. -> err.message = " + err.message);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> onFinished -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startUserBot -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function intitializeProcessFramework() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> Entering function."); }
+
+ processFramework.initialize(processConfig, statusDependencies, dataDependencies, onInizialized, dataDependencies);
+
+ function onInizialized(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> onInizialized -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write(MODULE_NAME, "[INFO] run -> loop -> intitializeProcessFramework -> onInizialized -> Execution finished well.");
+ startProcessFramework();
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Operation Failed. Aborting the process.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ case global.CUSTOM_OK_RESPONSE.result: {
+
+ switch (err.message) {
+ case "Too far in the future.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> intitializeProcessFramework -> onInizialized > Too far in the future. This Loop will enter in coma.");
+ nextWaitTime = 'Coma';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Not needed now, but soon.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> intitializeProcessFramework -> onInizialized > Not needed now, but soon. This Loop will continue with Normal wait time.");
+ nextWaitTime = 'Normal';
+ loopControl(nextWaitTime);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized > Unhandled custom response received. -> err.message = " + err.message);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> onInizialized -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> intitializeProcessFramework -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function startProcessFramework() {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> Entering function."); }
+
+ processFramework.start(onFinished);
+
+ function onFinished(err) {
+
+ try {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Entering function."); }
+
+ switch (err.result) {
+ case global.DEFAULT_OK_RESPONSE.result: {
+ logger.write(MODULE_NAME, "[INFO] run -> loop -> startProcessFramework -> onFinished -> Execution finished well.");
+ nextWaitTime = 'Normal';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_RETRY_RESPONSE.result: { // Something bad happened, but if we retry in a while it might go through the next time.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Retry Later. Requesting Execution Retry.");
+ nextWaitTime = 'Retry';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case global.DEFAULT_FAIL_RESPONSE.result: { // This is an unexpected exception that we do not know how to handle.
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Operation Failed. Aborting the process.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ case global.CUSTOM_OK_RESPONSE.result: {
+
+ switch (err.message) {
+ case "Dependency does not exist.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Dependency does not exist. This Loop will go to sleep.");
+ nextWaitTime = 'Sleep';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Dependency not ready.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Dependency not ready. This Loop will go to sleep.");
+ nextWaitTime = 'Sleep';
+ loopControl(nextWaitTime);
+ return;
+ }
+ case "Month before it is needed.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Month before it is needed. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ case "Month fully processed.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> Month fully processed. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ case "End of the month reached.": {
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> startProcessFramework -> onFinished -> End of the month reached. This Loop will be terminated.");
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled custom response received. -> err.message = " + err.message);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ return;
+ }
+ }
+ }
+ default: {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.result = " + err.result);
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> Unhandled err.result received. -> err.message = " + err.message);
+
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> onFinished -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> startProcessFramework -> err = ", err);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+
+ function loopControl(nextWaitTime) {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Entering function."); }
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> nextWaitTime = " + nextWaitTime); }
+
+ /* Here we check if we must stop the loop gracefully. */
+
+ shallWeStop(onStop, onContinue);
+
+ function onStop() {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Entering function."); }
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onStop -> Stopping the Loop Gracefully. See you next time!"); }
+
+ if (global.FULL_LOG === 'true') {
+ logger.persist();
+ }
+
+ callBackFunction(global.DEFAULT_OK_RESPONSE);
+ return;
+
+ }
+
+ function onContinue() {
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> onContinue -> Entering function."); }
+
+ /* Indicator bots are going to be executed after a configured period of time after the last execution ended. This is to avoid overlapping executions. */
+
+ switch (nextWaitTime) {
+ case 'Normal': {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.normalWaitTime / 1000) + " seconds."); }
+ checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.normalWaitTime * 5, bot.loopCounter);
+ nextLoopTimeoutHandle = setTimeout(loop, processConfig.normalWaitTime);
+ if (global.FULL_LOG === 'true') {
+ logger.persist();
+ }
+ }
+ break;
+ case 'Retry': {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.retryWaitTime / 1000) + " seconds."); }
+ checkLoopHealthHandle = setTimeout(checkLoopHealth, processConfig.retryWaitTime * 5, bot.loopCounter);
+ nextLoopTimeoutHandle = setTimeout(loop, processConfig.retryWaitTime);
+ logger.persist();
+ }
+ break;
+ case 'Sleep': {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.sleepWaitTime / 60000) + " minutes."); }
+ nextLoopTimeoutHandle = setTimeout(loop, processConfig.sleepWaitTime);
+ logger.persist();
+ }
+ break;
+ case 'Coma': {
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> loopControl -> Restarting Loop in " + (processConfig.comaWaitTime / 3600000) + " hours."); }
+ nextLoopTimeoutHandle = setTimeout(loop, processConfig.comaWaitTime);
+ logger.persist();
+ }
+ break;
+ }
+ }
+ }
+
+ function checkLoopHealth(pLastLoop) {
+
+ if (bot.enableCheckLoopHealth === false) {
+
+ logger.write(MODULE_NAME, "[WARN] run -> loop -> checkLoopHealth -> bot.enableCheckLoopHealth = " + bot.enableCheckLoopHealth);
+
+ return;
+ } // This gets disabled anytime the Main Loop is shut down by any condition.
+
+ if (bot.loopCounter <= pLastLoop + 1) { // This means that the next loop started but also stopped executing abruptally.
+
+ let now = new Date().valueOf();
+
+ if (now - bot.loopStartTime > processConfig.normalWaitTime) {
+
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> checkLoopHealth -> Dead loop found -> pLastLoop = " + pLastLoop);
+ console.log((new Date().toISOString() + " [ERROR] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found dead. Resurrecting it now."));
+
+ logger.persist(); // We persist the logs of the failed execution.
+ clearTimeout(nextLoopTimeoutHandle); // We cancel the timeout in case the original loop was still running and schedulled to reexecute.
+ loop(); // We restart the loop so that the processing can continue.
+
+ } else {
+
+ console.log((new Date().toISOString() + " [WARN] run -> loop -> checkLoopHealth -> " + pad(bot.codeName, 20) + " " + pad(bot.process, 30) + " Loop # " + pad(Number(bot.loopCounter), 5) + " found delayed but still alive. No action taken."));
+
+ }
+ }
+ }
+
+ function shallWeStop(stopCallBack, continueCallBack) {
+
+ try {
+
+ /* IMPORTANT: This function is exactly the same on the 3 modules. */
+
+ if (FULL_LOG === true) { logger.write(MODULE_NAME, "[INFO] run -> loop -> shallWeStop -> Entering function. "); }
+
+ let stop = false
+ if (process.env.STOP_GRACEFULLY !== undefined)
+ stop = JSON.parse(process.env.STOP_GRACEFULLY)
+
+ if (!stop && global.SHALL_BOT_STOP === false) {
+ continueCallBack();
+ } else {
+ stopCallBack();
+ }
+ } catch (err) {
+ logger.write(MODULE_NAME, "[ERROR] run -> loop -> shallWeStop -> err.message = " + err.message);
+ logger.persist();
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ return;
+ }
+ }
+ } catch (err) {
+ parentLogger.write(MODULE_NAME, "[ERROR] run -> loop -> err = ", err);
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(err);
+ }
+ }
+ } catch (err) {
+ parentLogger.write(MODULE_NAME, "[ERROR] run -> err = ", err);
+ clearInterval(fixedTimeLoopIntervalHandle);
+ clearTimeout(nextLoopTimeoutHandle);
+ clearTimeout(checkLoopHealthHandle);
+ bot.enableCheckLoopHealth = false;
+ callBackFunction(global.DEFAULT_FAIL_RESPONSE);
+ }
+ }
+};