proper-lockfile
Advanced tools
Comparing version 3.2.0 to 4.0.0
@@ -5,2 +5,22 @@ # Change Log | ||
<a name="4.0.0"></a> | ||
# [4.0.0](https://github.com/moxystudio/node-proper-lockfile/compare/v3.2.0...v4.0.0) (2019-03-12) | ||
### Bug Fixes | ||
* fix typo in error message ([#68](https://github.com/moxystudio/node-proper-lockfile/issues/68)) ([b91cb55](https://github.com/moxystudio/node-proper-lockfile/commit/b91cb55)) | ||
### Features | ||
* make staleness check more robust ([#74](https://github.com/moxystudio/node-proper-lockfile/issues/74)) ([9cc0973](https://github.com/moxystudio/node-proper-lockfile/commit/9cc0973)), closes [#71](https://github.com/moxystudio/node-proper-lockfile/issues/71) [/github.com/ipfs/js-ipfs-repo/issues/188#issuecomment-468682971](https://github.com//github.com/ipfs/js-ipfs-repo/issues/188/issues/issuecomment-468682971) | ||
### BREAKING CHANGES | ||
* We were marking the lock as compromised when system went into sleep or if the event loop was busy taking too long to run the internals timers, Now we keep track of the mtime updated by the current process, and if we lose some cycles in the update process but recover and the mtime is still ours we do not mark the lock as compromised. | ||
<a name="3.2.0"></a> | ||
@@ -7,0 +27,0 @@ # [3.2.0](https://github.com/moxystudio/node-proper-lockfile/compare/v3.1.0...v3.2.0) (2018-11-19) |
@@ -29,3 +29,3 @@ 'use strict'; | ||
if (!err) { | ||
return callback(); | ||
return options.fs.stat(getLockFile(file, options), callback); | ||
} | ||
@@ -40,3 +40,3 @@ | ||
if (options.stale <= 0) { | ||
return callback(Object.assign(new Error('Lock file is already being hold'), { code: 'ELOCKED', file })); | ||
return callback(Object.assign(new Error('Lock file is already being held'), { code: 'ELOCKED', file })); | ||
} | ||
@@ -98,33 +98,15 @@ | ||
lock.updateTimeout = setTimeout(() => { | ||
const mtime = Date.now() / 1000; | ||
lock.updateTimeout = null; | ||
options.fs.utimes(getLockFile(file, options), mtime, mtime, (err) => { | ||
// Ignore if the lock was released | ||
if (lock.released) { | ||
return; | ||
} | ||
// Check if mtime is still ours if it is we can still recover from a system sleep or a busy event loop | ||
options.fs.stat(getLockFile(file, options), (err, stat) => { | ||
const isOverThreshold = lock.lastUpdate + options.stale < Date.now(); | ||
// Verify if we are within the stale threshold | ||
if (lock.lastUpdate <= Date.now() - options.stale && lock.lastUpdate > Date.now() - (options.stale * 2)) { | ||
const err = Object.assign( | ||
new Error(lock.updateError || 'Unable to update lock within the stale threshold'), | ||
{ code: 'ECOMPROMISED' } | ||
); | ||
return setLockAsCompromised(file, lock, err); | ||
} | ||
// If the file is older than (stale * 2), we assume the clock is moved manually, | ||
// which we consider a valid case | ||
// If it failed to update the lockfile, keep trying unless | ||
// the lockfile was deleted! | ||
// the lockfile was deleted or we are over the threshold | ||
if (err) { | ||
if (err.code === 'ENOENT') { | ||
if (err.code === 'ENOENT' || isOverThreshold) { | ||
return setLockAsCompromised(file, lock, Object.assign(err, { code: 'ECOMPROMISED' })); | ||
} | ||
lock.updateError = err; | ||
lock.updateDelay = 1000; | ||
@@ -135,7 +117,42 @@ | ||
// All ok, keep updating.. | ||
lock.lastUpdate = Date.now(); | ||
lock.updateError = null; | ||
lock.updateDelay = null; | ||
updateLock(file, options); | ||
const isMtimeOurs = lock.mtime.getTime() === stat.mtime.getTime(); | ||
if (!isMtimeOurs) { | ||
return setLockAsCompromised( | ||
file, | ||
lock, | ||
Object.assign( | ||
new Error('Unable to update lock within the stale threshold'), | ||
{ code: 'ECOMPROMISED' } | ||
)); | ||
} | ||
const mtime = new Date(); | ||
options.fs.utimes(getLockFile(file, options), mtime, mtime, (err) => { | ||
const isOverThreshold = lock.lastUpdate + options.stale < Date.now(); | ||
// Ignore if the lock was released | ||
if (lock.released) { | ||
return; | ||
} | ||
// If it failed to update the lockfile, keep trying unless | ||
// the lockfile was deleted or we are over the threshold | ||
if (err) { | ||
if (err.code === 'ENOENT' || isOverThreshold) { | ||
return setLockAsCompromised(file, lock, Object.assign(err, { code: 'ECOMPROMISED' })); | ||
} | ||
lock.updateDelay = 1000; | ||
return updateLock(file, options); | ||
} | ||
// All ok, keep updating.. | ||
lock.mtime = mtime; | ||
lock.lastUpdate = Date.now(); | ||
lock.updateDelay = null; | ||
updateLock(file, options); | ||
}); | ||
}); | ||
@@ -205,3 +222,3 @@ }, lock.updateDelay); | ||
operation.attempt(() => { | ||
acquireLock(file, options, (err) => { | ||
acquireLock(file, options, (err, stat) => { | ||
if (operation.retry(err)) { | ||
@@ -217,2 +234,3 @@ return; | ||
const lock = locks[file] = { | ||
mtime: stat.mtime, | ||
options, | ||
@@ -219,0 +237,0 @@ lastUpdate: Date.now(), |
{ | ||
"name": "proper-lockfile", | ||
"version": "3.2.0", | ||
"version": "4.0.0", | ||
"description": "A inter-process and inter-machine lockfile utility that works on a local or network file system", | ||
@@ -32,3 +32,3 @@ "keywords": [ | ||
"scripts": { | ||
"posttag": "git push --follow-tags origin master && npm publish" | ||
"posttag": "git push --follow-tags origin master" | ||
} | ||
@@ -67,3 +67,3 @@ }, | ||
"husky": "^1.1.4", | ||
"jest": "^23.4.2", | ||
"jest": "^24.5.0", | ||
"lint-staged": "^8.0.4", | ||
@@ -74,4 +74,5 @@ "mkdirp": "^0.5.1", | ||
"stable": "^0.1.8", | ||
"standard-version": "^4.4.0" | ||
"standard-version": "^5.0.0", | ||
"thread-sleep": "^2.1.0" | ||
} | ||
} |
# proper-lockfile | ||
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] [![Greenkeeper badge][greenkeeper-image]][greenkeeper-url] | ||
[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Coverage Status][codecov-image]][codecov-url] [![Dependency status][david-dm-image]][david-dm-url] [![Dev Dependency status][david-dm-dev-image]][david-dm-dev-url] | ||
@@ -16,4 +16,2 @@ [npm-url]:https://npmjs.org/package/proper-lockfile | ||
[david-dm-dev-image]:https://img.shields.io/david/dev/moxystudio/node-proper-lockfile.svg | ||
[greenkeeper-image]:https://badges.greenkeeper.io/moxystudio/node-proper-lockfile.svg | ||
[greenkeeper-url]:https://greenkeeper.io/ | ||
@@ -20,0 +18,0 @@ An inter-process and inter-machine lockfile utility that works on a local or network file system. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26466
357
16
179