mirror of https://github.com/node-red/node-red.git
Prevent race condition (#1889)
* Make pending Flag to be deleted after write process complete. * Prevent executing write process until the previous process is completed * Fix to prevent file write race condition when closing file context * Make flushing rerun if pendingWrites was addedpull/1893/head
parent
a8ec032553
commit
fd86035865
|
@ -142,6 +142,7 @@ function LocalFileSystem(config){
|
||||||
this.storageBaseDir = getBasePath(this.config);
|
this.storageBaseDir = getBasePath(this.config);
|
||||||
if (config.hasOwnProperty('cache')?config.cache:true) {
|
if (config.hasOwnProperty('cache')?config.cache:true) {
|
||||||
this.cache = MemoryStore({});
|
this.cache = MemoryStore({});
|
||||||
|
this.writePromise = Promise.resolve();
|
||||||
}
|
}
|
||||||
this.pendingWrites = {};
|
this.pendingWrites = {};
|
||||||
this.knownCircularRefs = {};
|
this.knownCircularRefs = {};
|
||||||
|
@ -203,8 +204,22 @@ LocalFileSystem.prototype.open = function(){
|
||||||
log.debug("Flushing localfilesystem context scope "+scope);
|
log.debug("Flushing localfilesystem context scope "+scope);
|
||||||
promises.push(fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8"));
|
promises.push(fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8"));
|
||||||
});
|
});
|
||||||
delete self._pendingWriteTimeout;
|
return Promise.all(promises).then(function(){
|
||||||
return Promise.all(promises);
|
if(Object.keys(self.pendingWrites).length > 0){
|
||||||
|
// Rerun flushing if pendingWrites was added when the promise was running
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
setTimeout(function() {
|
||||||
|
self._flushPendingWrites.call(self).then(function(){
|
||||||
|
resolve();
|
||||||
|
}).catch(function(err) {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
}, self.flushInterval);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
delete self._pendingWriteTimeout;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -213,10 +228,16 @@ LocalFileSystem.prototype.open = function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFileSystem.prototype.close = function(){
|
LocalFileSystem.prototype.close = function(){
|
||||||
if (this.cache && this._flushPendingWrites) {
|
var self = this;
|
||||||
|
if (this.cache && this._pendingWriteTimeout) {
|
||||||
clearTimeout(this._pendingWriteTimeout);
|
clearTimeout(this._pendingWriteTimeout);
|
||||||
delete this._pendingWriteTimeout;
|
delete this._pendingWriteTimeout;
|
||||||
return this._flushPendingWrites();
|
this.flushInterval = 0;
|
||||||
|
return this.writePromise.then(function(){
|
||||||
|
if(Object.keys(self.pendingWrites).length > 0) {
|
||||||
|
return self._flushPendingWrites();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
@ -277,8 +298,10 @@ LocalFileSystem.prototype.set = function(scope, key, value, callback) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
this._pendingWriteTimeout = setTimeout(function() {
|
this._pendingWriteTimeout = setTimeout(function() {
|
||||||
self._flushPendingWrites.call(self).catch(function(err) {
|
self.writePromise = self.writePromise.then(function(){
|
||||||
log.error(log._("context.localfilesystem.error-write",{message:err.toString()}))
|
return self._flushPendingWrites.call(self).catch(function(err) {
|
||||||
|
log.error(log._("context.localfilesystem.error-write",{message:err.toString()}));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}, this.flushInterval);
|
}, this.flushInterval);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue