Skip to content

Commit

Permalink
Retry unlocking if EPERM
Browse files Browse the repository at this point in the history
See: #116
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed Oct 1, 2018
1 parent 71590c1 commit 2efed59
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 16 deletions.
87 changes: 87 additions & 0 deletions lib/lock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* The MIT License
*
* Copyright (c) 2018 Juan Cruz Viotti. https://github.com/jviotti
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

'use strict';

const lockFile = require('lockfile');

/**
* @summary Lock options
* @type {Object}
* @private
*/
const lockOptions = {
stale: 10000,
retries: Infinity,
retryWait: 50
};

/**
* @summary Create a lock file
* @function
* @public
*
* @param {String} file - lock file
* @param {Function} callback - callback (error)
*
* @example
* lock.lock('foo.lock', function(error) {
* if (error) {
* throw error;
* }
* })
*/
exports.lock = function(file, callback) {
lockFile.lock(file, lockOptions, callback);
};

/**
* @summary Unlock a lock file
* @function
* @public
*
* @param {String} file - lock file
* @param {Function} callback - callback (error)
*
* @example
* lock.unlock('foo.lock', function(error) {
* if (error) {
* throw error;
* }
* })
*/
exports.unlock = function(file, callback, times) {
times = times || 0;

lockFile.unlock(file, function(error) {
if (error && error.code === 'EPERM' && times < 10) {
setTimeout(function() {
exports.unlock(file, callback, times + 1);
}, 1000);
return;
}

return callback(error);
});
};
21 changes: 5 additions & 16 deletions lib/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,7 @@ const rimraf = require('rimraf');
const mkdirp = require('mkdirp');
const path = require('path');
const utils = require('./utils');
const lockFile = require('lockfile');

/**
* @summary Lock options
* @type {Object}
* @private
*/
const lockOptions = {
stale: 10000,
retries: Infinity,
retryWait: 50
};
const lock = require('./lock');

/**
* @summary Get the default data path
Expand Down Expand Up @@ -143,7 +132,7 @@ exports.get = function(key, options, callback) {
mkdirp(path.dirname(fileName), callback);
},
function(made, next) {
lockFile.lock(utils.getLockFileName(fileName), lockOptions, function(error) {
lock.lock(utils.getLockFileName(fileName), function(error) {
if (error && error.code === 'EEXIST') {
return exports.get(key, options, callback);
}
Expand Down Expand Up @@ -176,7 +165,7 @@ exports.get = function(key, options, callback) {
return callback(null, objectJSON);
}
], function(error, result) {
lockFile.unlock(utils.getLockFileName(fileName), function(lockError) {
lock.unlock(utils.getLockFileName(fileName), function(lockError) {
if (error) {
return callback(error);
}
Expand Down Expand Up @@ -319,7 +308,7 @@ exports.set = function(key, json, options, callback) {
});
},
function(data, next) {
lockFile.lock(utils.getLockFileName(fileName), lockOptions, function(error) {
lock.lock(utils.getLockFileName(fileName), function(error) {
if (error && error.code === 'EEXIST') {
return exports.set(key, json, options, callback);
}
Expand All @@ -331,7 +320,7 @@ exports.set = function(key, json, options, callback) {
fs.writeFile(fileName, data, callback);
}
], function(error) {
lockFile.unlock(utils.getLockFileName(fileName), function(lockError) {
lock.unlock(utils.getLockFileName(fileName), function(lockError) {
if (error) {
return callback(error);
}
Expand Down

0 comments on commit 2efed59

Please sign in to comment.