MVP-9756: Added event handling for function node

This commit is contained in:
michaeltreyvaud 2024-01-11 08:48:40 +00:00
parent fe189e0f38
commit e8edb4437b

View File

@ -17,6 +17,111 @@
const clone = require("clone");
const PayloadValidator = require("../../PayloadValidator");
const processServisbotActions = (originalMessage, message) => {
if (message.servisbot && message.servisbot.actions && Array.isArray(message.servisbot.actions) && message.servisbot.actions.length > 0) {
message.servisbot.actions.forEach((action) => {
const [func, args] = action;
if (originalMessage && originalMessage.servisbot && originalMessage.servisbot[func]) {
originalMessage.servisbot[func](args);
}
});
}
}
const handleCodeFile = async (node, sendResults, {
logger, msg, codefile, afterVm2
}) => {
const {
payload: {
system: { organization },
},
event: {
workers: [{ id: workerId }],
},
} = msg;
const workId = workerId.split(':::')[0];
const nodeId = node.id.split(`${organization}-${workId}-`)[1];
try {
const beforeCodefile = process.hrtime();
const {
payload: {
result,
error
},
requestId
} = await codefile.run({
srcCode: node.func,
context: {
msg,
node: {
id: nodeId,
name: node.name
}
}
});
const afterCodefile = process.hrtime(beforeCodefile);
const metrics = {
lambdaRequestId: requestId,
action: 'codefile-success',
organization,
workerId,
nodeId,
rawCode: node.func,
vm2Runtime: `${
Math.floor((afterVm2[0] * 1e9 + afterVm2[1]) / 10000) / 100
}ms`,
codefileRuntime: `${
Math.floor(
(afterCodefile[0] * 1e9 + afterCodefile[1]) / 10000
) / 100
}ms`,
};
if (result) {
const payloadValidator = new PayloadValidator(msg, node.id);
payloadValidator.verify(result);
// Re-attach logger to msgs as they get lost when passing over to the lambda
let messageToForward = result;
if (Array.isArray(result)) {
// Array result, re-attach logger and process any servisbot.log actions returned from the lambda
messageToForward = result.map((_res) => {
if (_res !== null && typeof _res === 'object') {
_res.logger = logger;
processServisbotActions(msg, _res);
if (msg.servisbot) {
_res.servisbot = msg.servisbot;
}
}
return _res;
});
} else if (typeof result === 'object') {
result.logger = logger;
processServisbotActions(msg, result);
if (msg.servisbot) {
result.servisbot = msg.servisbot;
}
}
sendResults(node, msg._msgid, messageToForward);
} else {
metrics.error = error;
metrics.action = 'codefile-error';
}
logger.info(metrics);
} catch (e) {
logger.error(e);
logger.error({
message: 'Error running codefile',
action: 'codefile-error',
error: e.message,
organization,
workerId,
nodeId,
rawCode: node.func,
});
}
};
module.exports = function (RED) {
"use strict";
var util = require("util");
@ -228,22 +333,13 @@ module.exports = function (RED) {
const payloadValidator = new PayloadValidator(msg, this.id);
var start = process.hrtime();
sandbox.msg = msg;
const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 });
// const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 });
const beforeVm2 = process.hrtime();
const result = vm2Instance.run(functionText);
// const result = vm2Instance.run(functionText);
const afterVm2 = process.hrtime(beforeVm2);
payloadValidator.verify(result);
sendResults(this, msg._msgid, result);
// payloadValidator.verify(result);
// sendResults(this, msg._msgid, result);
const logger = clone(msg.logger);
let lambdaRequestId;
let {
payload: {
system: { organization },
},
event: {
workers: [{ id: workerId }],
},
} = originalMessage;
const {
settings: {
@ -252,66 +348,14 @@ module.exports = function (RED) {
} = RED;
if (codefile) {
workerId = workerId.split(":::")[0];
const nodeId = this.id.split(`${organization}-${workerId}-`)[1];
try {
const messageToSend = clone(msg);
delete messageToSend.logger;
const beforeCodefile = process.hrtime();
const {
payload: {
result,
error
},
requestId
} = await codefile.run({ srcCode: this.func, context: { msg } });
const afterCodefile = process.hrtime(beforeCodefile);
const metrics = {
lambdaRequestId: requestId,
action:'codefile-success',
organization,
workerId: workerId,
nodeId: nodeId,
rawCode: this.func,
vm2Runtime: `${
Math.floor((afterVm2[0] * 1e9 + afterVm2[1]) / 10000) / 100
}ms`,
codefileRuntime: `${
Math.floor(
(afterCodefile[0] * 1e9 + afterCodefile[1]) / 10000
) / 100
}ms`,
};
if(result){
// not required right now since we dont go via this path
// const responseMessage = result.msg
// responseMessage.logger = logger;
// payloadValidator.verify(responseMessage);
// sendResults(this,msg._msgid, responseMessage);
}
else{
metrics.error = error;
metrics.action = 'codefile-error';
}
logger.info(metrics);
} catch (e) {
logger.error(e)
logger.error({
message: "Error running codefile",
action:'codefile-error',
error: e.message,
organization,
workerId: workerId,
nodeId: nodeId,
rawCode: this.func,
await handleCodeFile(this, sendResults, {
logger,
msg: originalMessage,
codefile,
afterVm2,
});
}
}
// sendResults(this,msg._msgid, responseMessage);
var duration = process.hrtime(start);
var converted =
Math.floor((duration[0] * 1e9 + duration[1]) / 10000) / 100;
@ -386,3 +430,4 @@ module.exports = function (RED) {
RED.nodes.registerType("function", FunctionNode);
RED.library.register("functions");
};