mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
MVP-9756: Added event handling for function node
This commit is contained in:
parent
fe189e0f38
commit
e8edb4437b
@ -17,6 +17,111 @@
|
|||||||
const clone = require("clone");
|
const clone = require("clone");
|
||||||
const PayloadValidator = require("../../PayloadValidator");
|
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) {
|
module.exports = function (RED) {
|
||||||
"use strict";
|
"use strict";
|
||||||
var util = require("util");
|
var util = require("util");
|
||||||
@ -228,22 +333,13 @@ module.exports = function (RED) {
|
|||||||
const payloadValidator = new PayloadValidator(msg, this.id);
|
const payloadValidator = new PayloadValidator(msg, this.id);
|
||||||
var start = process.hrtime();
|
var start = process.hrtime();
|
||||||
sandbox.msg = msg;
|
sandbox.msg = msg;
|
||||||
const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 });
|
// const vm2Instance = new vm2.VM({ sandbox, timeout: 5000 });
|
||||||
const beforeVm2 = process.hrtime();
|
const beforeVm2 = process.hrtime();
|
||||||
const result = vm2Instance.run(functionText);
|
// const result = vm2Instance.run(functionText);
|
||||||
const afterVm2 = process.hrtime(beforeVm2);
|
const afterVm2 = process.hrtime(beforeVm2);
|
||||||
payloadValidator.verify(result);
|
// payloadValidator.verify(result);
|
||||||
sendResults(this, msg._msgid, result);
|
// sendResults(this, msg._msgid, result);
|
||||||
const logger = clone(msg.logger);
|
const logger = clone(msg.logger);
|
||||||
let lambdaRequestId;
|
|
||||||
let {
|
|
||||||
payload: {
|
|
||||||
system: { organization },
|
|
||||||
},
|
|
||||||
event: {
|
|
||||||
workers: [{ id: workerId }],
|
|
||||||
},
|
|
||||||
} = originalMessage;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
settings: {
|
settings: {
|
||||||
@ -252,66 +348,14 @@ module.exports = function (RED) {
|
|||||||
} = RED;
|
} = RED;
|
||||||
|
|
||||||
if (codefile) {
|
if (codefile) {
|
||||||
workerId = workerId.split(":::")[0];
|
await handleCodeFile(this, sendResults, {
|
||||||
const nodeId = this.id.split(`${organization}-${workerId}-`)[1];
|
logger,
|
||||||
try {
|
msg: originalMessage,
|
||||||
const messageToSend = clone(msg);
|
codefile,
|
||||||
delete messageToSend.logger;
|
afterVm2,
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// sendResults(this,msg._msgid, responseMessage);
|
|
||||||
var duration = process.hrtime(start);
|
var duration = process.hrtime(start);
|
||||||
var converted =
|
var converted =
|
||||||
Math.floor((duration[0] * 1e9 + duration[1]) / 10000) / 100;
|
Math.floor((duration[0] * 1e9 + duration[1]) / 10000) / 100;
|
||||||
@ -386,3 +430,4 @@ module.exports = function (RED) {
|
|||||||
RED.nodes.registerType("function", FunctionNode);
|
RED.nodes.registerType("function", FunctionNode);
|
||||||
RED.library.register("functions");
|
RED.library.register("functions");
|
||||||
};
|
};
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user