Use a more atomic process for writing context files

Fixes #2271
This commit is contained in:
Nick O'Leary 2019-08-21 16:54:26 +01:00
parent 74eec25285
commit 10077ae750
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
1 changed files with 12 additions and 2 deletions

View File

@ -137,6 +137,16 @@ function stringify(value) {
return { json: result, circular: hasCircular };
}
function writeFileAtomic(storagePath, content) {
// To protect against file corruption, write to a tmp file first and then
// rename to the destination file
let finalFile = storagePath + ".json";
let tmpFile = finalFile + "."+Date.now()+".tmp";
return fs.outputFile(tmpFile, content, "utf8").then(function() {
return fs.rename(tmpFile,finalFile);
})
}
function LocalFileSystem(config){
this.config = config;
this.storageBaseDir = getBasePath(this.config);
@ -202,7 +212,7 @@ LocalFileSystem.prototype.open = function(){
delete self.knownCircularRefs[scope];
}
log.debug("Flushing localfilesystem context scope "+scope);
promises.push(fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8"));
promises.push(writeFileAtomic(storagePath, stringifiedContext.json))
});
delete self._pendingWriteTimeout;
return Promise.all(promises);
@ -319,7 +329,7 @@ LocalFileSystem.prototype.set = function(scope, key, value, callback) {
} else {
delete self.knownCircularRefs[scope];
}
return fs.outputFile(storagePath + ".json", stringifiedContext.json, "utf8");
return writeFileAtomic(storagePath, stringifiedContext.json);
}).then(function(){
if(typeof callback === "function"){
callback(null);