UNPKG

process-rerun

Version:

The purpose of this library is - build simple and flexible interface for parallel command execution with rerun (on fail) possibility

87 lines 4.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildExecRunner = buildExecRunner; /* eslint-disable sonarjs/cognitive-complexity */ const sat_utils_1 = require("sat-utils"); const logger_execution_1 = require("./logger.execution"); const exec_1 = require("./exec"); const logger_1 = require("./logger"); const error_1 = require("./error"); function buildExecRunner(notRetriable, runOpts) { const { currentExecutionVariable, longestProcessTime, processResultAnalyzer, execOpts = { maxBuffer: 1000 * 1024 }, pollTime, successExitCode = 0, logProcessResult = logger_execution_1.internalLogProcessResult, onExitCloseProcess, onErrorProcess, } = runOpts; if (!(0, sat_utils_1.isNumber)(successExitCode)) { throw new error_1.ProcessRerunError('Type', 'successExitCode should be a number'); } return (cmd, index) => new Promise(resolve => { const onErrorCloseHandler = null; const executionHolder = { stackTrace: '' }; /** * @now this variable will be used for process kill if time more than @longestProcessTime */ const startTime = +Date.now(); if (currentExecutionVariable) { cmd = cmd.includes(currentExecutionVariable) ? cmd.replace(new RegExp(`${currentExecutionVariable}=\\d+`, 'ig'), `${currentExecutionVariable}=${index}`) : `${currentExecutionVariable}=${index} ${cmd}`; } const execProc = (0, exec_1.execute)(cmd, logProcessResult, executionHolder, execOpts); const killTooLongExecution = (procWhatShouldBeKilled) => { const executionTime = +Date.now() - startTime; if (executionTime > longestProcessTime) { if (executionTime - longestProcessTime > 7500) { procWhatShouldBeKilled.emit('exit', 100, 'PRO_RERUN_KILL'); procWhatShouldBeKilled.emit('close', 100, 'PRO_RERUN_KILL'); logger_1.logger.error(`Process just marked manually as killed but it is possible that it is still running`); } else { logger_1.logger.info(`Process killed due to long time execution: ${(0, sat_utils_1.millisecondsToMinutes)(executionTime)}\n${cmd}}`); process.kill(procWhatShouldBeKilled.pid); } } }; const watcher = setInterval(() => killTooLongExecution(execProc), pollTime); if (onExitCloseProcess) { execProc.on('exit', (code, signal) => onExitCloseProcess(execProc, code, signal)); } if (onErrorProcess) { execProc.on('error', error => onErrorProcess(execProc, error)); } execProc.on('close', async (code, signal) => { if (onExitCloseProcess) { onExitCloseProcess(execProc, code, signal); } // clear watcher interval clearInterval(watcher); if (onErrorCloseHandler && ((0, sat_utils_1.isFunction)(onErrorCloseHandler) || (0, sat_utils_1.isAsyncFunction)(onErrorCloseHandler))) { await onErrorCloseHandler(); } // if process code 0 - exit as a success result if (code === successExitCode) { return resolve(null); } // processResultAnalyzer - check that stack contains or not contains some specific data if ((0, sat_utils_1.isFunction)(processResultAnalyzer)) { const countInNotRetriableBeforeAnalyzation = notRetriable.length; const analyzationResult = processResultAnalyzer(cmd, executionHolder.stackTrace, notRetriable); if (!(0, sat_utils_1.isString)(analyzationResult) && !(0, sat_utils_1.isBoolean)(analyzationResult)) { logger_1.logger.warn('processResultAnalyzer should return boolean or string'); } // if analyzationResult is string - we want to re-execute command if ((0, sat_utils_1.isString)(analyzationResult)) { return resolve(analyzationResult); } // if analyzationResult is true - we make assumption that process was finished successfully if ((0, sat_utils_1.isBoolean)(analyzationResult) && analyzationResult) { return resolve(null); } if (countInNotRetriableBeforeAnalyzation === notRetriable.length || ((0, sat_utils_1.isBoolean)(analyzationResult) && !analyzationResult)) { notRetriable.push(cmd); } return resolve(null); } return resolve(cmd); }); }); } //# sourceMappingURL=exec.proc.js.map