mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Remove all Promises from Switch node
Promises are expensive and should not be used in the main message handling path. The Switch node used them a lot if the node references context - with a lot of duplicate code to handle async and sync code paths. This change modifies the code to use callbacks throughout that are just as performant in either case.
This commit is contained in:
parent
7f5d47f39d
commit
473a2ae275
@ -91,206 +91,117 @@ module.exports = function(RED) {
|
|||||||
return _maxKeptCount;
|
return _maxKeptCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProperty(node,msg) {
|
function getProperty(node,msg,done) {
|
||||||
if (node.useAsyncRules) {
|
if (node.propertyType === 'jsonata') {
|
||||||
return new Promise((resolve,reject) => {
|
RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
|
||||||
if (node.propertyType === 'jsonata') {
|
if (err) {
|
||||||
RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
|
done(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
if (err) {
|
|
||||||
reject(RED._("switch.errors.invalid-expr",{error:err.message}));
|
|
||||||
} else {
|
|
||||||
resolve(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg,(err,value) => {
|
done(undefined,value);
|
||||||
if (err) {
|
|
||||||
resolve(undefined);
|
|
||||||
} else {
|
|
||||||
resolve(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (node.propertyType === 'jsonata') {
|
RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg,(err,value) => {
|
||||||
try {
|
if (err) {
|
||||||
return RED.util.evaluateJSONataExpression(node.property,msg);
|
done(undefined,undefined);
|
||||||
} catch(err) {
|
} else {
|
||||||
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
done(undefined,value);
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
try {
|
|
||||||
return RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
|
|
||||||
} catch(err) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getV1(node,msg,rule,hasParts) {
|
function getV1(node,msg,rule,hasParts,done) {
|
||||||
if (node.useAsyncRules) {
|
if (rule.vt === 'prev') {
|
||||||
return new Promise( (resolve,reject) => {
|
return done(undefined,node.previousValue);
|
||||||
if (rule.vt === 'prev') {
|
} else if (rule.vt === 'jsonata') {
|
||||||
resolve(node.previousValue);
|
var exp = rule.v;
|
||||||
} else if (rule.vt === 'jsonata') {
|
if (rule.t === 'jsonata_exp') {
|
||||||
var exp = rule.v;
|
if (hasParts) {
|
||||||
if (rule.t === 'jsonata_exp') {
|
exp.assign("I", msg.parts.index);
|
||||||
if (hasParts) {
|
exp.assign("N", msg.parts.count);
|
||||||
exp.assign("I", msg.parts.index);
|
}
|
||||||
exp.assign("N", msg.parts.count);
|
}
|
||||||
}
|
RED.util.evaluateJSONataExpression(exp,msg,(err,value) => {
|
||||||
}
|
if (err) {
|
||||||
RED.util.evaluateJSONataExpression(exp,msg,(err,value) => {
|
done(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
if (err) {
|
|
||||||
reject(RED._("switch.errors.invalid-expr",{error:err.message}));
|
|
||||||
} else {
|
|
||||||
resolve(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (rule.vt === 'json') {
|
|
||||||
resolve("json"); // TODO: ?! invalid case
|
|
||||||
} else if (rule.vt === 'null') {
|
|
||||||
resolve("null");
|
|
||||||
} else {
|
} else {
|
||||||
RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg, function(err,value) {
|
done(undefined, value);
|
||||||
if (err) {
|
}
|
||||||
resolve(undefined);
|
});
|
||||||
} else {
|
} else if (rule.vt === 'json') {
|
||||||
resolve(value);
|
done(undefined,"json"); // TODO: ?! invalid case
|
||||||
}
|
} else if (rule.vt === 'null') {
|
||||||
});
|
done(undefined,"null");
|
||||||
|
} else {
|
||||||
|
RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg, function(err,value) {
|
||||||
|
if (err) {
|
||||||
|
done(undefined, undefined);
|
||||||
|
} else {
|
||||||
|
done(undefined, value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getV2(node,msg,rule,done) {
|
||||||
|
var v2 = rule.v2;
|
||||||
|
if (rule.v2t === 'prev') {
|
||||||
|
return done(undefined,node.previousValue);
|
||||||
|
} else if (rule.v2t === 'jsonata') {
|
||||||
|
RED.util.evaluateJSONataExpression(rule.v2,msg,(err,value) => {
|
||||||
|
if (err) {
|
||||||
|
done(RED._("switch.errors.invalid-expr",{error:err.message}));
|
||||||
|
} else {
|
||||||
|
done(undefined,value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (typeof v2 !== 'undefined') {
|
||||||
|
RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg, function(err,value) {
|
||||||
|
if (err) {
|
||||||
|
done(undefined,undefined);
|
||||||
|
} else {
|
||||||
|
done(undefined,value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (rule.vt === 'prev') {
|
done(undefined,v2);
|
||||||
return node.previousValue;
|
|
||||||
} else if (rule.vt === 'jsonata') {
|
|
||||||
var exp = rule.v;
|
|
||||||
if (rule.t === 'jsonata_exp') {
|
|
||||||
if (hasParts) {
|
|
||||||
exp.assign("I", msg.parts.index);
|
|
||||||
exp.assign("N", msg.parts.count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return RED.util.evaluateJSONataExpression(exp,msg);
|
|
||||||
} catch(err) {
|
|
||||||
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
|
||||||
}
|
|
||||||
} else if (rule.vt === 'json') {
|
|
||||||
return "json"; // TODO: ?! invalid case
|
|
||||||
} else if (rule.vt === 'null') {
|
|
||||||
return "null";
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
return RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
|
|
||||||
} catch(err) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getV2(node,msg,rule) {
|
function applyRule(node, msg, property, state, done) {
|
||||||
if (node.useAsyncRules) {
|
var rule = node.rules[state.currentRule];
|
||||||
return new Promise((resolve,reject) => {
|
var v1,v2;
|
||||||
var v2 = rule.v2;
|
|
||||||
if (rule.v2t === 'prev') {
|
getV1(node,msg,rule,state.hasParts, (err,value) => {
|
||||||
resolve(node.previousValue);
|
if (err) {
|
||||||
} else if (rule.v2t === 'jsonata') {
|
return done(err);
|
||||||
RED.util.evaluateJSONataExpression(rule.v2,msg,(err,value) => {
|
}
|
||||||
if (err) {
|
v1 = value;
|
||||||
reject(RED._("switch.errors.invalid-expr",{error:err.message}));
|
getV2(node,msg,rule, (err,value) => {
|
||||||
} else {
|
if (err) {
|
||||||
resolve(value);
|
return done(err);
|
||||||
}
|
}
|
||||||
});
|
v2 = value;
|
||||||
} else if (typeof v2 !== 'undefined') {
|
if (rule.t == "else") {
|
||||||
RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg, function(err,value) {
|
property = state.elseflag;
|
||||||
if (err) {
|
state.elseflag = true;
|
||||||
resolve(undefined);
|
}
|
||||||
} else {
|
if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
|
||||||
resolve(value);
|
state.onward.push(msg);
|
||||||
}
|
state.elseflag = false;
|
||||||
});
|
if (node.checkall == "false") {
|
||||||
|
return done(undefined,false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
resolve(v2);
|
state.onward.push(null);
|
||||||
}
|
}
|
||||||
})
|
done(undefined, state.currentRule < node.rules.length - 1);
|
||||||
} else {
|
});
|
||||||
var v2 = rule.v2;
|
});
|
||||||
if (rule.v2t === 'prev') {
|
|
||||||
return node.previousValue;
|
|
||||||
} else if (rule.v2t === 'jsonata') {
|
|
||||||
try {
|
|
||||||
return RED.util.evaluateJSONataExpression(rule.v2,msg);
|
|
||||||
} catch(err) {
|
|
||||||
throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
|
|
||||||
}
|
|
||||||
} else if (typeof v2 !== 'undefined') {
|
|
||||||
try {
|
|
||||||
return RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
|
|
||||||
} catch(err) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return v2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyRule(node, msg, property, state) {
|
function applyRules(node, msg, property,state,done) {
|
||||||
if (node.useAsyncRules) {
|
|
||||||
return new Promise((resolve,reject) => {
|
|
||||||
|
|
||||||
var rule = node.rules[state.currentRule];
|
|
||||||
var v1,v2;
|
|
||||||
|
|
||||||
getV1(node,msg,rule,state.hasParts).then(value => {
|
|
||||||
v1 = value;
|
|
||||||
}).then(()=>getV2(node,msg,rule)).then(value => {
|
|
||||||
v2 = value;
|
|
||||||
}).then(() => {
|
|
||||||
if (rule.t == "else") {
|
|
||||||
property = state.elseflag;
|
|
||||||
state.elseflag = true;
|
|
||||||
}
|
|
||||||
if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
|
|
||||||
state.onward.push(msg);
|
|
||||||
state.elseflag = false;
|
|
||||||
if (node.checkall == "false") {
|
|
||||||
return resolve(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.onward.push(null);
|
|
||||||
}
|
|
||||||
resolve(state.currentRule < node.rules.length - 1);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
var rule = node.rules[state.currentRule];
|
|
||||||
var v1 = getV1(node,msg,rule,state.hasParts);
|
|
||||||
var v2 = getV2(node,msg,rule);
|
|
||||||
if (rule.t == "else") {
|
|
||||||
property = state.elseflag;
|
|
||||||
state.elseflag = true;
|
|
||||||
}
|
|
||||||
if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
|
|
||||||
state.onward.push(msg);
|
|
||||||
state.elseflag = false;
|
|
||||||
if (node.checkall == "false") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.onward.push(null);
|
|
||||||
}
|
|
||||||
return state.currentRule < node.rules.length - 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyRules(node, msg, property,state) {
|
|
||||||
if (!state) {
|
if (!state) {
|
||||||
state = {
|
state = {
|
||||||
currentRule: 0,
|
currentRule: 0,
|
||||||
@ -301,26 +212,18 @@ module.exports = function(RED) {
|
|||||||
msg.parts.hasOwnProperty("index")
|
msg.parts.hasOwnProperty("index")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.useAsyncRules) {
|
applyRule(node,msg,property,state,(err,hasMore) => {
|
||||||
return applyRule(node,msg,property,state).then(hasMore => {
|
if (err) {
|
||||||
if (hasMore) {
|
return done(err);
|
||||||
state.currentRule++;
|
}
|
||||||
return applyRules(node,msg,property,state);
|
|
||||||
} else {
|
|
||||||
node.previousValue = property;
|
|
||||||
return state.onward;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var hasMore = applyRule(node,msg,property,state);
|
|
||||||
if (hasMore) {
|
if (hasMore) {
|
||||||
state.currentRule++;
|
state.currentRule++;
|
||||||
return applyRules(node,msg,property,state);
|
applyRules(node,msg,property,state,done);
|
||||||
} else {
|
} else {
|
||||||
node.previousValue = property;
|
node.previousValue = property;
|
||||||
return state.onward;
|
done(undefined,state.onward);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -345,13 +248,6 @@ module.exports = function(RED) {
|
|||||||
var valid = true;
|
var valid = true;
|
||||||
var repair = n.repair;
|
var repair = n.repair;
|
||||||
var needsCount = repair;
|
var needsCount = repair;
|
||||||
this.useAsyncRules = (
|
|
||||||
this.propertyType === 'flow' ||
|
|
||||||
this.propertyType === 'global' || (
|
|
||||||
this.propertyType === 'jsonata' &&
|
|
||||||
/\$(flow|global)Context/.test(this.property)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (var i=0; i<this.rules.length; i+=1) {
|
for (var i=0; i<this.rules.length; i+=1) {
|
||||||
var rule = this.rules[i];
|
var rule = this.rules[i];
|
||||||
@ -363,13 +259,6 @@ module.exports = function(RED) {
|
|||||||
rule.vt = 'str';
|
rule.vt = 'str';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.useAsyncRules = this.useAsyncRules || (
|
|
||||||
rule.vt === 'flow' ||
|
|
||||||
rule.vt === 'global' || (
|
|
||||||
rule.vt === 'jsonata' &&
|
|
||||||
/\$(flow|global)Context/.test(rule.v)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (rule.vt === 'num') {
|
if (rule.vt === 'num') {
|
||||||
if (!isNaN(Number(rule.v))) {
|
if (!isNaN(Number(rule.v))) {
|
||||||
rule.v = Number(rule.v);
|
rule.v = Number(rule.v);
|
||||||
@ -382,9 +271,6 @@ module.exports = function(RED) {
|
|||||||
valid = false;
|
valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rule.vt === 'flow' || rule.vt === 'global' || rule.vt === 'jsonata') {
|
|
||||||
this.useAsyncRules = true;
|
|
||||||
}
|
|
||||||
if (typeof rule.v2 !== 'undefined') {
|
if (typeof rule.v2 !== 'undefined') {
|
||||||
if (!rule.v2t) {
|
if (!rule.v2t) {
|
||||||
if (!isNaN(Number(rule.v2))) {
|
if (!isNaN(Number(rule.v2))) {
|
||||||
@ -393,13 +279,6 @@ module.exports = function(RED) {
|
|||||||
rule.v2t = 'str';
|
rule.v2t = 'str';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.useAsyncRules = this.useAsyncRules || (
|
|
||||||
rule.v2t === 'flow' ||
|
|
||||||
rule.v2t === 'global' || (
|
|
||||||
rule.v2t === 'jsonata' &&
|
|
||||||
/\$(flow|global)Context/.test(rule.v2)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
if (rule.v2t === 'num') {
|
if (rule.v2t === 'num') {
|
||||||
rule.v2 = Number(rule.v2);
|
rule.v2 = Number(rule.v2);
|
||||||
} else if (rule.v2t === 'jsonata') {
|
} else if (rule.v2t === 'jsonata') {
|
||||||
@ -444,26 +323,38 @@ module.exports = function(RED) {
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drainMessageGroup(msgs,count,done) {
|
||||||
function addMessageToPending(msg) {
|
var msg = msgs.shift();
|
||||||
|
msg.parts.count = count;
|
||||||
|
processMessage(msg,false, err => {
|
||||||
|
if (err) {
|
||||||
|
done(err);
|
||||||
|
} else {
|
||||||
|
if (msgs.length === 0) {
|
||||||
|
done()
|
||||||
|
} else {
|
||||||
|
drainMessageGroup(msgs,count,done);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function addMessageToPending(msg,done) {
|
||||||
var parts = msg.parts;
|
var parts = msg.parts;
|
||||||
// We've already checked the msg.parts has the require bits
|
// We've already checked the msg.parts has the require bits
|
||||||
var group = addMessageToGroup(parts.id, msg, parts);
|
var group = addMessageToGroup(parts.id, msg, parts);
|
||||||
var msgs = group.msgs;
|
var msgs = group.msgs;
|
||||||
var count = group.count;
|
var count = group.count;
|
||||||
if (count === msgs.length) {
|
var msgsCount = msgs.length;
|
||||||
|
if (count === msgsCount) {
|
||||||
// We have a complete group - send the individual parts
|
// We have a complete group - send the individual parts
|
||||||
return msgs.reduce((promise, msg) => {
|
drainMessageGroup(msgs,count,err => {
|
||||||
return promise.then((result) => {
|
pendingCount -= msgsCount;
|
||||||
msg.parts.count = count;
|
|
||||||
return processMessage(msg, false);
|
|
||||||
})
|
|
||||||
}, Promise.resolve()).then( () => {
|
|
||||||
pendingCount -= group.msgs.length;
|
|
||||||
delete pendingIn[parts.id];
|
delete pendingIn[parts.id];
|
||||||
});
|
done();
|
||||||
|
})
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendGroup(onwards, port_count) {
|
function sendGroup(onwards, port_count) {
|
||||||
@ -529,43 +420,33 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function processMessage(msg, checkParts, done) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function processMessage(msg, checkParts) {
|
|
||||||
var hasParts = msg.hasOwnProperty("parts") &&
|
var hasParts = msg.hasOwnProperty("parts") &&
|
||||||
msg.parts.hasOwnProperty("id") &&
|
msg.parts.hasOwnProperty("id") &&
|
||||||
msg.parts.hasOwnProperty("index");
|
msg.parts.hasOwnProperty("index");
|
||||||
|
|
||||||
if (needsCount && checkParts && hasParts) {
|
if (needsCount && checkParts && hasParts) {
|
||||||
return addMessageToPending(msg);
|
addMessageToPending(msg,done);
|
||||||
}
|
|
||||||
if (node.useAsyncRules) {
|
|
||||||
return getProperty(node,msg)
|
|
||||||
.then(property => applyRules(node,msg,property))
|
|
||||||
.then(onward => {
|
|
||||||
if (!repair || !hasParts) {
|
|
||||||
node.send(onward);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sendGroupMessages(onward, msg);
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
node.warn(err);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
try {
|
getProperty(node,msg,(err,property) => {
|
||||||
var property = getProperty(node,msg);
|
if (err) {
|
||||||
var onward = applyRules(node,msg,property);
|
node.warn(err);
|
||||||
if (!repair || !hasParts) {
|
done();
|
||||||
node.send(onward);
|
|
||||||
} else {
|
} else {
|
||||||
sendGroupMessages(onward, msg);
|
applyRules(node,msg,property,undefined,(err,onward) => {
|
||||||
|
if (err) {
|
||||||
|
node.warn(err);
|
||||||
|
} else {
|
||||||
|
if (!repair || !hasParts) {
|
||||||
|
node.send(onward);
|
||||||
|
} else {
|
||||||
|
sendGroupMessages(onward, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
done();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch(err) {
|
});
|
||||||
node.warn(err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,12 +459,13 @@ module.exports = function(RED) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pendingMessages = [];
|
var pendingMessages = [];
|
||||||
var activeMessagePromise = null;
|
var handlingMessage = false;
|
||||||
var processMessageQueue = function(msg) {
|
var processMessageQueue = function(msg) {
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
|
||||||
// A new message has arrived - add it to the message queue
|
// A new message has arrived - add it to the message queue
|
||||||
pendingMessages.push(msg);
|
pendingMessages.push(msg);
|
||||||
if (activeMessagePromise !== null) {
|
if (handlingMessage) {
|
||||||
// The node is currently processing a message, so do nothing
|
// The node is currently processing a message, so do nothing
|
||||||
// more with this message
|
// more with this message
|
||||||
return;
|
return;
|
||||||
@ -592,27 +474,24 @@ module.exports = function(RED) {
|
|||||||
if (pendingMessages.length === 0) {
|
if (pendingMessages.length === 0) {
|
||||||
// There are no more messages to process, clear the active flag
|
// There are no more messages to process, clear the active flag
|
||||||
// and return
|
// and return
|
||||||
activeMessagePromise = null;
|
handlingMessage = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// There are more messages to process. Get the next message and
|
// There are more messages to process. Get the next message and
|
||||||
// start processing it. Recurse back in to check for any more
|
// start processing it. Recurse back in to check for any more
|
||||||
var nextMsg = pendingMessages.shift();
|
var nextMsg = pendingMessages.shift();
|
||||||
activeMessagePromise = processMessage(nextMsg,true)
|
handlingMessage = true;
|
||||||
.then(processMessageQueue)
|
processMessage(nextMsg,true,err => {
|
||||||
.catch((err) => {
|
if (err) {
|
||||||
node.error(err,nextMsg);
|
node.error(err,nextMsg);
|
||||||
return processMessageQueue();
|
}
|
||||||
});
|
processMessageQueue()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.on('input', function(msg) {
|
this.on('input', function(msg) {
|
||||||
if (node.useAsyncRules) {
|
processMessageQueue(msg);
|
||||||
processMessageQueue(msg);
|
|
||||||
} else {
|
|
||||||
processMessage(msg,true);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('close', function() {
|
this.on('close', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user