diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js index bd782256c..343739626 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js @@ -308,6 +308,17 @@ class Flow { removedMap[id] = true; }); + let nodesToStop = []; + let configsToStop = []; + stopList.forEach(id => { + if (this.flow.configs[id]) { + configsToStop.push(id); + } else { + nodesToStop.push(id); + } + }); + stopList = nodesToStop.concat(configsToStop); + var promises = []; for (i=0;i { if (activeFlows.hasOwnProperty(id)) { var flowStateChanged = diff && (diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1); log.debug("red/nodes/flows.stop : stopping flow : "+id); @@ -413,10 +421,10 @@ function stop(type,diff,muteLog) { delete activeFlows[id]; } } - } + }); return Promise.all(promises).then(function() { - for (id in activeNodesToFlow) { + for (let id in activeNodesToFlow) { if (activeNodesToFlow.hasOwnProperty(id)) { if (!activeFlows[activeNodesToFlow[id]]) { delete activeNodesToFlow[id]; diff --git a/test/unit/@node-red/runtime/lib/flows/Flow_spec.js b/test/unit/@node-red/runtime/lib/flows/Flow_spec.js index bc27aaaef..1a5230c76 100644 --- a/test/unit/@node-red/runtime/lib/flows/Flow_spec.js +++ b/test/unit/@node-red/runtime/lib/flows/Flow_spec.js @@ -34,6 +34,7 @@ describe('Flow', function() { var getType; var stoppedNodes = {}; + var stoppedOrder = []; var currentNodes = {}; var rewiredNodes = {}; var createCount = 0; @@ -41,6 +42,7 @@ describe('Flow', function() { beforeEach(function() { currentNodes = {}; stoppedNodes = {}; + stoppedOrder =[]; rewiredNodes = {}; createCount = 0; Flow.init({settings:{},log:{ @@ -71,6 +73,7 @@ describe('Flow', function() { this.on('close',function() { node.stopped = true; stoppedNodes[node.id] = node; + stoppedOrder.push(node.id) delete currentNodes[node.id]; }); this.__updateWires = this.updateWires; @@ -99,6 +102,7 @@ describe('Flow', function() { this.on('close',function() { node.stopped = true; stoppedNodes[node.id] = node; + stoppedOrder.push(node.id) delete currentNodes[node.id]; }); this.__updateWires = this.updateWires; @@ -131,6 +135,7 @@ describe('Flow', function() { setTimeout(function() { node.stopped = true; stoppedNodes[node.id] = node; + stoppedOrder.push(node.id) delete currentNodes[node.id]; done(); },node.closeDelay); @@ -159,6 +164,7 @@ describe('Flow', function() { setTimeout(function() { node.stopped = true; stoppedNodes[node.id] = node; + stoppedOrder.push(node.id) delete currentNodes[node.id]; done(); },node.closeDelay); @@ -461,6 +467,34 @@ describe('Flow', function() { }); }); + it("stops config nodes last",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:"c1",z:"t1",type:"test"}, + {id:"2",x:10,y:10,z:"t1",type:"test",foo:"a",wires:["3"]}, + {id:"c2",z:"t1",type:"test"}, + {id:"3",x:10,y:10,z:"t1",type:"test",foo:"a",wires:[]}, + {id:"c3",z:"t1",type:"test"} + ]); + var flow = Flow.create({},config,config.flows["t1"]); + flow.start(); + + currentNodes.should.have.a.property("1"); + currentNodes.should.have.a.property("2"); + currentNodes.should.have.a.property("3"); + currentNodes.should.have.a.property("c1"); + currentNodes.should.have.a.property("c2"); + currentNodes.should.have.a.property("c3"); + stoppedOrder.should.have.a.length(0); + + flow.stop().then(function() { + stoppedOrder.should.eql([ '1', '2', '3', 'c1', 'c2', 'c3' ]); + done(); + }).catch(done); + }); + + it("Times out a node that fails to close", function(done) { Flow.init({settings:{nodeCloseTimeout:50},log:{ log: sinon.stub(),