Fix race condition on saving config

This commit is contained in:
Nick O'Leary 2014-09-23 17:09:23 +01:00
parent 6305c5b55f
commit 9152daa13b
5 changed files with 54 additions and 18 deletions

View File

@ -118,6 +118,7 @@ module.exports = {
getNodeConfigs: registry.getNodeConfigs,
getNodeConfig: registry.getNodeConfig,
clearRegistry: registry.clear,
cleanNodeList: registry.cleanNodeList,
// Flow handling
loadFlows: flows.load,

View File

@ -69,7 +69,11 @@ var registry = (function() {
nodeList[i] = n;
}
}
settings.set("nodes",nodeList);
if (settings.available()) {
return settings.set("nodes",nodeList);
} else {
return when.reject("Settings unavailable");
}
}
return {
@ -271,7 +275,22 @@ var registry = (function() {
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) {
// Trigger a load of the configs to get it precached
registry.getAllNodeConfigs();
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) {
registry.saveNodeList();
var list = results.map(function(r) {
return filterNodeInfo(r.value);
return registry.saveNodeList().then(function() {
var list = results.map(function(r) {
return filterNodeInfo(r.value);
});
return list;
});
return list;
});
}
@ -666,5 +688,6 @@ module.exports = {
disableNode: registry.disableNodeSet,
addModule: addModule,
removeModule: registry.removeModule
removeModule: registry.removeModule,
cleanNodeList: registry.cleanNodeList
}

View File

@ -330,13 +330,19 @@ function start() {
var promises = [];
for (i in missingModules) {
if (missingModules.hasOwnProperty(i)) {
util.log(" - "+i+": "+missingModules[i].join(", "));
installModule(i).otherwise(function(err) {
// Error already reported. Need the otherwise handler
// to stop the error propagating any further
});
util.log("[red] - "+i+": "+missingModules[i].join(", "));
if (settings.autoInstallModules) {
installModule(i).otherwise(function(err) {
// 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();

View File

@ -216,7 +216,12 @@ var localfilesystem = {
if (fs.existsSync(globalSettingsFile)) {
return nodeFn.call(fs.readFile,globalSettingsFile,'utf8').then(function(data) {
if (data) {
return JSON.parse(data);
try {
return JSON.parse(data);
} catch(err) {
util.log("[red] Corrupted config detected - resetting");
return {};
}
} else {
return {};
}

View File

@ -17,6 +17,7 @@
var should = require("should");
var sinon = require("sinon");
var path = require("path");
var when = require("when");
var RedNodes = require("../../../red/nodes");
var RedNode = require("../../../red/nodes/Node");
@ -33,7 +34,7 @@ describe('NodeRegistry', function() {
function stubSettings(s,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;}
return s
}
@ -294,7 +295,7 @@ describe('NodeRegistry', function() {
var settings = {
nodesDir:[resourcesDir + "TestNode1",resourcesDir + "TestNode2",resourcesDir + "TestNode3"],
available: function() { return true; },
set: function(s,v) {},
set: function(s,v) {return when.resolve();},
get: function(s) { return null;}
}
var settingsSave = sinon.spy(settings,"set");
@ -327,7 +328,7 @@ describe('NodeRegistry', function() {
it('allows nodes to be added by filename', function(done) {
var settings = {
available: function() { return true; },
set: function(s,v) {},
set: function(s,v) {return when.resolve();},
get: function(s) { return null;}
}
typeRegistry.init(settings);