mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Ensure config nodes are instantiated in the right order
This commit is contained in:
parent
2a089f7d90
commit
b744491dd2
@ -36,17 +36,40 @@ function Flow(global,flow) {
|
|||||||
var id;
|
var id;
|
||||||
catchNodeMap = {};
|
catchNodeMap = {};
|
||||||
statusNodeMap = {};
|
statusNodeMap = {};
|
||||||
for (id in flow.configs) {
|
|
||||||
if (flow.configs.hasOwnProperty(id)) {
|
var configNodes = Object.keys(flow.configs);
|
||||||
node = flow.configs[id];
|
var configNodeAttempts = {};
|
||||||
if (!activeNodes[id]) {
|
while(configNodes.length > 0) {
|
||||||
|
id = configNodes.shift();
|
||||||
|
node = flow.configs[id];
|
||||||
|
if (!activeNodes[id]) {
|
||||||
|
var readyToCreate = true;
|
||||||
|
// This node doesn't exist.
|
||||||
|
// Check it doesn't reference another non-existent config node
|
||||||
|
for (var prop in node) {
|
||||||
|
if (node.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== '_users' && flow.configs[node[prop]]) {
|
||||||
|
if (!activeNodes[node[prop]]) {
|
||||||
|
// References a non-existent config node
|
||||||
|
// Add it to the back of the list to try again later
|
||||||
|
configNodes.push(id);
|
||||||
|
configNodeAttempts[id] = (configNodeAttempts[id]||0)+1;
|
||||||
|
if (configNodeAttempts[id] === 100) {
|
||||||
|
throw new Error("Circular config node dependency detected: "+id);
|
||||||
|
}
|
||||||
|
readyToCreate = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (readyToCreate) {
|
||||||
newNode = createNode(node.type,node);
|
newNode = createNode(node.type,node);
|
||||||
if (newNode) {
|
if (newNode) {
|
||||||
activeNodes[id] = newNode;
|
activeNodes[id] = newNode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if (diff && diff.rewired) {
|
if (diff && diff.rewired) {
|
||||||
for (var j=0;j<diff.rewired.length;j++) {
|
for (var j=0;j<diff.rewired.length;j++) {
|
||||||
var rewireNode = activeNodes[diff.rewired[j]];
|
var rewireNode = activeNodes[diff.rewired[j]];
|
||||||
|
@ -45,7 +45,7 @@ describe('Flow', function() {
|
|||||||
|
|
||||||
var TestNode = function(n) {
|
var TestNode = function(n) {
|
||||||
Node.call(this,n);
|
Node.call(this,n);
|
||||||
createCount++;
|
this._index = createCount++;
|
||||||
this.scope = n.scope;
|
this.scope = n.scope;
|
||||||
var node = this;
|
var node = this;
|
||||||
this.foo = n.foo;
|
this.foo = n.foo;
|
||||||
@ -173,6 +173,61 @@ describe('Flow', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("instantiates config nodes in the right order",function(done) {
|
||||||
|
var config = flowUtils.parseConfig([
|
||||||
|
{id:"t1",type:"tab"},
|
||||||
|
{id:"1",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["2"]},
|
||||||
|
{id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]},
|
||||||
|
{id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]},
|
||||||
|
{id:"4",z:"t1",type:"test",foo:"5"}, // This node depends on #5
|
||||||
|
{id:"5",z:"t1",type:"test"}
|
||||||
|
]);
|
||||||
|
var flow = Flow.create(config,config.flows["t1"]);
|
||||||
|
flow.start();
|
||||||
|
|
||||||
|
Object.keys(flow.getActiveNodes()).should.have.length(5);
|
||||||
|
|
||||||
|
|
||||||
|
currentNodes.should.have.a.property("1");
|
||||||
|
currentNodes.should.have.a.property("2");
|
||||||
|
currentNodes.should.have.a.property("3");
|
||||||
|
currentNodes.should.have.a.property("4");
|
||||||
|
currentNodes.should.have.a.property("5");
|
||||||
|
|
||||||
|
currentNodes["1"].should.have.a.property("_index",2);
|
||||||
|
currentNodes["2"].should.have.a.property("_index",3);
|
||||||
|
currentNodes["3"].should.have.a.property("_index",4);
|
||||||
|
currentNodes["4"].should.have.a.property("_index",1);
|
||||||
|
currentNodes["5"].should.have.a.property("_index",0);
|
||||||
|
|
||||||
|
flow.stop().then(function() {
|
||||||
|
currentNodes.should.not.have.a.property("1");
|
||||||
|
currentNodes.should.not.have.a.property("2");
|
||||||
|
currentNodes.should.not.have.a.property("3");
|
||||||
|
currentNodes.should.not.have.a.property("4");
|
||||||
|
currentNodes.should.not.have.a.property("5");
|
||||||
|
stoppedNodes.should.have.a.property("1");
|
||||||
|
stoppedNodes.should.have.a.property("2");
|
||||||
|
stoppedNodes.should.have.a.property("3");
|
||||||
|
stoppedNodes.should.have.a.property("4");
|
||||||
|
stoppedNodes.should.have.a.property("5");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it("detects dependency loops in config nodes",function() {
|
||||||
|
var config = flowUtils.parseConfig([
|
||||||
|
{id:"t1",type:"tab"},
|
||||||
|
{id:"node1",z:"t1",type:"test",foo:"node2"}, // This node depends on #5
|
||||||
|
{id:"node2",z:"t1",type:"test",foo:"node1"}
|
||||||
|
]);
|
||||||
|
var flow = Flow.create(config,config.flows["t1"]);
|
||||||
|
/*jshint immed: false */
|
||||||
|
(function(){
|
||||||
|
flow.start();
|
||||||
|
}).should.throw("Circular config node dependency detected: node1");
|
||||||
|
});
|
||||||
it("instantiates a subflow and stops it",function(done) {
|
it("instantiates a subflow and stops it",function(done) {
|
||||||
var config = flowUtils.parseConfig([
|
var config = flowUtils.parseConfig([
|
||||||
{id:"t1",type:"tab"},
|
{id:"t1",type:"tab"},
|
||||||
|
Loading…
Reference in New Issue
Block a user