const fs = require('fs');
const path = require('path');
// Returns a temporary file
// Example: for /some/file will return /some/.~file
function getTempFile(file) {
return path.join(path.dirname(file), `.~${path.basename(file)}`);
}
const _writeFile = Symbol('writeFile');
class Persistence {
constructor(file) {
this.file = file;
this.dataQueue = [];
this.lock = false;
}
write(data) {
if (this.lock) {
// File is locked - save data for later
this.dataQueue.push(data);
return;
}
const toWrite = this.dataQueue.length ? this.dataQueue[0] : data;
// File is not locked - lock it
this.lock = true;
this[_writeFile](this.file, toWrite).then(() => {
// Remove the data from the queue
this.dataQueue.shift();
// Unlock file
this.lock = false;
if (this.dataQueue.length) {
this.write(this.dataQueue[0]);
}
});
}
remove() {
console.log('removing collection from persistence');
Eif (this.lock) {
// File is locked - save data for later
console.log('file is currently being written to');
return;
}
// File is not locked - lock it
this.lock = true;
fs.unlinkSync(this.file);
this.lock = false;
}
[_writeFile](file, data) {
// Write data to a temporary file
const tmpFile = getTempFile(this.file);
return new Promise(resolve => {
fs.writeFile(tmpFile, data, (writeErr) => {
if (writeErr) {
console.log('There was a write error:', writeErr);
return;
}
// On success rename the temporary file to the real file
fs.rename(tmpFile, this.file, (renameErr) => {
if (renameErr) {
console.log('There was a rename error:', renameErr);
return;
}
resolve();
});
});
});
}
}
module.exports = {
Persistence
};
|