From 97283416266861534b488c4aced3f5c11aa987ac Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Sun, 2 Dec 2018 12:10:42 +0000 Subject: [PATCH] Retry on EPERM when locking and reading See: https://github.com/electron-userland/electron-json-storage/issues/116 Signed-off-by: Juan Cruz Viotti --- lib/lock.js | 17 ++++++++++++++--- lib/storage.js | 39 ++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/lib/lock.js b/lib/lock.js index a38a84a..7f9724e 100644 --- a/lib/lock.js +++ b/lib/lock.js @@ -33,7 +33,7 @@ const lockFile = require('lockfile'); */ const lockOptions = { stale: 10000, - retries: Infinity, + retries: 1000, retryWait: 50 }; @@ -52,8 +52,19 @@ const lockOptions = { * } * }) */ -exports.lock = function(file, callback) { - lockFile.lock(file, lockOptions, callback); +exports.lock = function(file, callback, times) { + times = times || 0; + + lockFile.lock(file, lockOptions, function(error) { + if (error && error.code === 'EPERM' && times < 10) { + setTimeout(function() { + exports.unlock(file, callback, times + 1); + }, 1000); + return; + } + + return callback(error); + }); }; /** diff --git a/lib/storage.js b/lib/storage.js index 8828cd0..ee7f5f6 100644 --- a/lib/storage.js +++ b/lib/storage.js @@ -37,6 +37,31 @@ const path = require('path'); const utils = require('./utils'); const lock = require('./lock'); +const readFile = function(fileName, callback, times) { + times = times || 0; + + fs.readFile(fileName, { + encoding: 'utf8' + }, function(error, object) { + if (!error) { + return callback(null, object); + } + + if (error.code === 'ENOENT') { + return callback(null, JSON.stringify({})); + } + + if (error.code === 'EPERM' && times < 10) { + setTimeout(function() { + readFile(fileName, callback, times + 1); + }, 1000); + return; + } + + return callback(error); + }); +}; + /** * @summary Get the default data path * @function @@ -141,19 +166,7 @@ exports.get = function(key, options, callback) { }); }, function(callback) { - fs.readFile(fileName, { - encoding: 'utf8' - }, function(error, object) { - if (!error) { - return callback(null, object); - } - - if (error.code === 'ENOENT') { - return callback(null, JSON.stringify({})); - } - - return callback(error); - }); + readFile(fileName, callback); }, function(object, callback) { var objectJSON = {};