mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Fix race condition on saving config
This commit is contained in:
		@@ -118,6 +118,7 @@ module.exports = {
 | 
				
			|||||||
    getNodeConfigs: registry.getNodeConfigs,
 | 
					    getNodeConfigs: registry.getNodeConfigs,
 | 
				
			||||||
    getNodeConfig: registry.getNodeConfig,
 | 
					    getNodeConfig: registry.getNodeConfig,
 | 
				
			||||||
    clearRegistry: registry.clear,
 | 
					    clearRegistry: registry.clear,
 | 
				
			||||||
 | 
					    cleanNodeList: registry.cleanNodeList,
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Flow handling
 | 
					    // Flow handling
 | 
				
			||||||
    loadFlows: flows.load,
 | 
					    loadFlows: flows.load,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,7 +69,11 @@ var registry = (function() {
 | 
				
			|||||||
                nodeList[i] = n;
 | 
					                nodeList[i] = n;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        settings.set("nodes",nodeList);
 | 
					        if (settings.available()) {
 | 
				
			||||||
 | 
					            return settings.set("nodes",nodeList);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return when.reject("Settings unavailable");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@@ -271,7 +275,22 @@ var registry = (function() {
 | 
				
			|||||||
            return filterNodeInfo(config);
 | 
					            return filterNodeInfo(config);
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        saveNodeList: saveNodeList
 | 
					        saveNodeList: saveNodeList,
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        cleanNodeList: function() {
 | 
				
			||||||
 | 
					            var removed = false;
 | 
				
			||||||
 | 
					            for (var id in nodeConfigs) {
 | 
				
			||||||
 | 
					                if (nodeConfigs.hasOwnProperty(id)) {
 | 
				
			||||||
 | 
					                    if (nodeConfigs[id].module && !nodeModules[nodeConfigs[id].module]) {
 | 
				
			||||||
 | 
					                        registry.removeNode(id);
 | 
				
			||||||
 | 
					                        removed = true;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (removed) {
 | 
				
			||||||
 | 
					                saveNodeList();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
})();
 | 
					})();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -547,10 +566,12 @@ function load(defaultNodesDir,disableNodePathScan) {
 | 
				
			|||||||
        when.settle(promises).then(function(results) {
 | 
					        when.settle(promises).then(function(results) {
 | 
				
			||||||
            // Trigger a load of the configs to get it precached
 | 
					            // Trigger a load of the configs to get it precached
 | 
				
			||||||
            registry.getAllNodeConfigs();
 | 
					            registry.getAllNodeConfigs();
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            if (settings.available()) {
 | 
					            if (settings.available()) {
 | 
				
			||||||
                registry.saveNodeList();
 | 
					                resolve(registry.saveNodeList());
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                resolve();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            resolve();
 | 
					 | 
				
			||||||
        }); 
 | 
					        }); 
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -608,11 +629,12 @@ function loadNodeList(nodes) {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return when.settle(promises).then(function(results) {
 | 
					    return when.settle(promises).then(function(results) {
 | 
				
			||||||
        registry.saveNodeList();
 | 
					        return registry.saveNodeList().then(function() {
 | 
				
			||||||
        var list = results.map(function(r) {
 | 
					            var list = results.map(function(r) {
 | 
				
			||||||
            return filterNodeInfo(r.value);
 | 
					                return filterNodeInfo(r.value);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            return list;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        return list;
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -666,5 +688,6 @@ module.exports = {
 | 
				
			|||||||
    disableNode: registry.disableNodeSet,
 | 
					    disableNode: registry.disableNodeSet,
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    addModule: addModule,
 | 
					    addModule: addModule,
 | 
				
			||||||
    removeModule: registry.removeModule
 | 
					    removeModule: registry.removeModule,
 | 
				
			||||||
 | 
					    cleanNodeList: registry.cleanNodeList
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -330,13 +330,19 @@ function start() {
 | 
				
			|||||||
                    var promises = [];
 | 
					                    var promises = [];
 | 
				
			||||||
                    for (i in missingModules) {
 | 
					                    for (i in missingModules) {
 | 
				
			||||||
                        if (missingModules.hasOwnProperty(i)) {
 | 
					                        if (missingModules.hasOwnProperty(i)) {
 | 
				
			||||||
                            util.log(" - "+i+": "+missingModules[i].join(", "));
 | 
					                            util.log("[red] - "+i+": "+missingModules[i].join(", "));
 | 
				
			||||||
                            installModule(i).otherwise(function(err) {
 | 
					                            if (settings.autoInstallModules) {
 | 
				
			||||||
                                // Error already reported. Need the otherwise handler
 | 
					                                installModule(i).otherwise(function(err) {
 | 
				
			||||||
                                // to stop the error propagating any further
 | 
					                                    // Error already reported. Need the otherwise handler
 | 
				
			||||||
                            });
 | 
					                                    // to stop the error propagating any further
 | 
				
			||||||
 | 
					                                });
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (!settings.autoInstallModules) {
 | 
				
			||||||
 | 
					                        util.log("[red] Removing modules from config");
 | 
				
			||||||
 | 
					                        redNodes.cleanNodeList();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                defer.resolve();
 | 
					                defer.resolve();
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -216,7 +216,12 @@ var localfilesystem = {
 | 
				
			|||||||
        if (fs.existsSync(globalSettingsFile)) {
 | 
					        if (fs.existsSync(globalSettingsFile)) {
 | 
				
			||||||
            return nodeFn.call(fs.readFile,globalSettingsFile,'utf8').then(function(data) {
 | 
					            return nodeFn.call(fs.readFile,globalSettingsFile,'utf8').then(function(data) {
 | 
				
			||||||
                if (data) {
 | 
					                if (data) {
 | 
				
			||||||
                    return JSON.parse(data);
 | 
					                    try {
 | 
				
			||||||
 | 
					                        return JSON.parse(data);
 | 
				
			||||||
 | 
					                    } catch(err) {
 | 
				
			||||||
 | 
					                        util.log("[red] Corrupted config detected - resetting");
 | 
				
			||||||
 | 
					                        return {};
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    return {};
 | 
					                    return {};
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
var should = require("should");
 | 
					var should = require("should");
 | 
				
			||||||
var sinon = require("sinon");
 | 
					var sinon = require("sinon");
 | 
				
			||||||
var path = require("path");
 | 
					var path = require("path");
 | 
				
			||||||
 | 
					var when = require("when");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var RedNodes = require("../../../red/nodes");
 | 
					var RedNodes = require("../../../red/nodes");
 | 
				
			||||||
var RedNode = require("../../../red/nodes/Node");
 | 
					var RedNode = require("../../../red/nodes/Node");
 | 
				
			||||||
@@ -33,7 +34,7 @@ describe('NodeRegistry', function() {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    function stubSettings(s,available) {
 | 
					    function stubSettings(s,available) {
 | 
				
			||||||
        s.available =  function() {return available;}
 | 
					        s.available =  function() {return available;}
 | 
				
			||||||
        s.set = function(s,v) {},
 | 
					        s.set = function(s,v) { return when.resolve()},
 | 
				
			||||||
        s.get = function(s) { return null;}
 | 
					        s.get = function(s) { return null;}
 | 
				
			||||||
        return s
 | 
					        return s
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -294,7 +295,7 @@ describe('NodeRegistry', function() {
 | 
				
			|||||||
        var settings = {
 | 
					        var settings = {
 | 
				
			||||||
            nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2",resourcesDir + "TestNode3"],
 | 
					            nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2",resourcesDir + "TestNode3"],
 | 
				
			||||||
            available: function() { return true; },
 | 
					            available: function() { return true; },
 | 
				
			||||||
            set: function(s,v) {},
 | 
					            set: function(s,v) {return when.resolve();},
 | 
				
			||||||
            get: function(s) { return null;}
 | 
					            get: function(s) { return null;}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        var settingsSave = sinon.spy(settings,"set");
 | 
					        var settingsSave = sinon.spy(settings,"set");
 | 
				
			||||||
@@ -327,7 +328,7 @@ describe('NodeRegistry', function() {
 | 
				
			|||||||
    it('allows nodes to be added by filename', function(done) {
 | 
					    it('allows nodes to be added by filename', function(done) {
 | 
				
			||||||
        var settings = {
 | 
					        var settings = {
 | 
				
			||||||
            available: function() { return true; },
 | 
					            available: function() { return true; },
 | 
				
			||||||
            set: function(s,v) {},
 | 
					            set: function(s,v) {return when.resolve();},
 | 
				
			||||||
            get: function(s) { return null;}
 | 
					            get: function(s) { return null;}
 | 
				
			||||||
        }            
 | 
					        }            
 | 
				
			||||||
        typeRegistry.init(settings);
 | 
					        typeRegistry.init(settings);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user