diff --git a/msa/js-executor/api/jsInvokeMessageProcessor.js b/msa/js-executor/api/jsInvokeMessageProcessor.js index 6afc02e89c..ac14bcbd57 100644 --- a/msa/js-executor/api/jsInvokeMessageProcessor.js +++ b/msa/js-executor/api/jsInvokeMessageProcessor.js @@ -27,11 +27,13 @@ const config = require('config'), const scriptBodyTraceFrequency = Number(config.get('script.script_body_trace_frequency')); const useSandbox = config.get('script.use_sandbox') === 'true'; +const maxActiveScripts = Number(config.get('script.max_active_scripts')); function JsInvokeMessageProcessor(producer) { this.producer = producer; this.executor = new JsExecutor(useSandbox); this.scriptMap = {}; + this.scriptIds = []; this.executedScriptsCounter = 0; } @@ -70,7 +72,7 @@ JsInvokeMessageProcessor.prototype.processCompileRequest = function(requestId, r this.executor.compileScript(compileRequest.scriptBody).then( (script) => { - this.scriptMap[scriptId] = script; + this.cacheScript(scriptId, script); var compileResponse = createCompileResponse(scriptId, true); logger.debug('[%s] Sending success compile response, scriptId: [%s]', requestId, scriptId); this.sendResponse(requestId, responseTopic, scriptId, compileResponse); @@ -126,6 +128,10 @@ JsInvokeMessageProcessor.prototype.processReleaseRequest = function(requestId, r var scriptId = getScriptId(releaseRequest); logger.debug('[%s] Processing release request, scriptId: [%s]', requestId, scriptId); if (this.scriptMap[scriptId]) { + var index = this.scriptIds.indexOf(scriptId); + if (index > -1) { + this.scriptIds.splice(index, 1); + } delete this.scriptMap[scriptId]; } var releaseResponse = createReleaseResponse(scriptId, true); @@ -165,7 +171,7 @@ JsInvokeMessageProcessor.prototype.getOrCompileScript = function(scriptId, scrip } else { self.executor.compileScript(scriptBody).then( (script) => { - self.scriptMap[scriptId] = script; + self.cacheScript(scriptId, script); resolve(script); }, (err) => { @@ -176,6 +182,19 @@ JsInvokeMessageProcessor.prototype.getOrCompileScript = function(scriptId, scrip }); } +JsInvokeMessageProcessor.prototype.cacheScript = function(scriptId, script) { + if (!this.scriptMap[scriptId]) { + this.scriptIds.push(scriptId); + while (this.scriptIds.length > maxActiveScripts) { + logger.info('Active scripts count [%s] exceeds maximum limit [%s]', this.scriptIds.length, maxActiveScripts); + const prevScriptId = this.scriptIds.shift(); + logger.info('Removing active script with id [%s]', prevScriptId); + delete this.scriptMap[prevScriptId]; + } + } + this.scriptMap[scriptId] = script; +} + function createRemoteResponse(requestId, compileResponse, invokeResponse, releaseResponse) { const requestIdBits = Utils.UUIDToBits(requestId); return { diff --git a/msa/js-executor/config/custom-environment-variables.yml b/msa/js-executor/config/custom-environment-variables.yml index c3caf15a9a..22b1082f72 100644 --- a/msa/js-executor/config/custom-environment-variables.yml +++ b/msa/js-executor/config/custom-environment-variables.yml @@ -27,3 +27,4 @@ logger: script: use_sandbox: "SCRIPT_USE_SANDBOX" script_body_trace_frequency: "SCRIPT_BODY_TRACE_FREQUENCY" + max_active_scripts: "MAX_ACTIVE_SCRIPTS" diff --git a/msa/js-executor/config/default.yml b/msa/js-executor/config/default.yml index 9688722109..95a847a5bb 100644 --- a/msa/js-executor/config/default.yml +++ b/msa/js-executor/config/default.yml @@ -28,3 +28,4 @@ logger: script: use_sandbox: "true" script_body_trace_frequency: "1000" + max_active_scripts: "1000"