mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Ensure config nodes are instantiated in the right order
This commit is contained in:
		@@ -36,17 +36,40 @@ function Flow(global,flow) {
 | 
			
		||||
        var id;
 | 
			
		||||
        catchNodeMap = {};
 | 
			
		||||
        statusNodeMap = {};
 | 
			
		||||
        for (id in flow.configs) {
 | 
			
		||||
            if (flow.configs.hasOwnProperty(id)) {
 | 
			
		||||
                node = flow.configs[id];
 | 
			
		||||
                if (!activeNodes[id]) {
 | 
			
		||||
 | 
			
		||||
        var configNodes = Object.keys(flow.configs);
 | 
			
		||||
        var configNodeAttempts = {};
 | 
			
		||||
        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);
 | 
			
		||||
                    if (newNode) {
 | 
			
		||||
                        activeNodes[id] = newNode;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (diff && diff.rewired) {
 | 
			
		||||
            for (var j=0;j<diff.rewired.length;j++) {
 | 
			
		||||
                var rewireNode = activeNodes[diff.rewired[j]];
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ describe('Flow', function() {
 | 
			
		||||
 | 
			
		||||
    var TestNode = function(n) {
 | 
			
		||||
        Node.call(this,n);
 | 
			
		||||
        createCount++;
 | 
			
		||||
        this._index = createCount++;
 | 
			
		||||
        this.scope = n.scope;
 | 
			
		||||
        var node = this;
 | 
			
		||||
        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) {
 | 
			
		||||
            var config = flowUtils.parseConfig([
 | 
			
		||||
                {id:"t1",type:"tab"},
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user