Comparing version 0.4.3 to 1.0.0
@@ -140,13 +140,23 @@ var fs = require('fs') | ||
debug('lock', path, opts) | ||
opts.start = opts.start || Date.now() | ||
if (typeof opts.retries === 'number' && opts.retries > 0) { | ||
cb = (function (orig) { return function (er, fd) { | ||
if (!er) return orig(er, fd) | ||
var newRT = opts.retries - 1 | ||
opts_ = Object.create(opts, { retries: { value: newRT }}) | ||
debug('lock retry', path, newRT) | ||
if (opts.retryWait) setTimeout(function() { | ||
exports.lock(path, opts_, orig) | ||
}, opts.retryWait) | ||
else exports.lock(path, opts_, orig) | ||
debug('has retries', opts.retries) | ||
var retries = opts.retries | ||
opts.retries = 0 | ||
cb = (function (orig) { return function cb (er, fd) { | ||
debug('retry-mutated callback') | ||
retries -= 1 | ||
if (!er || retries < 0) return orig(er, fd) | ||
debug('lock retry', path, opts) | ||
if (opts.retryWait) setTimeout(retry, opts.retryWait) | ||
else retry() | ||
function retry () { | ||
opts.start = Date.now() | ||
debug('retrying', opts.start) | ||
exports.lock(path, opts, cb) | ||
} | ||
}})(cb) | ||
@@ -192,5 +202,5 @@ } | ||
// expired already! | ||
var opts_ = Object.create(opts, { stale: { value: false }}) | ||
debug('lock stale enoent retry', path, opts_) | ||
exports.lock(path, opts_, cb) | ||
opts.stale = false | ||
debug('lock stale enoent retry', path, opts) | ||
exports.lock(path, opts, cb) | ||
return | ||
@@ -204,3 +214,3 @@ } | ||
debug('lock stale', path, opts_) | ||
debug('lock stale', path, opts) | ||
if (hasStaleLock) { | ||
@@ -234,16 +244,18 @@ exports.unlock(path, function (er) { | ||
// console.error('wait', path, opts.wait) | ||
// wait for some ms for the lock to clear | ||
var start = Date.now() | ||
// poll for some ms for the lock to clear | ||
var now = Date.now() | ||
var start = opts.start || now | ||
var end = start + opts.wait | ||
function retry () { | ||
debug('notStale retry', path, opts) | ||
var now = Date.now() | ||
var newWait = end - now | ||
var newOpts = Object.create(opts, { wait: { value: newWait }}) | ||
exports.lock(path, newOpts, cb) | ||
if (end <= now) | ||
return cb(er) | ||
debug('now=%d, wait until %d (delta=%d)', start, end, end-start) | ||
var wait = Math.min(end - start, opts.pollPeriod || 100) | ||
var timer = setTimeout(poll, wait) | ||
function poll () { | ||
debug('notStale, polling', path, opts) | ||
exports.lock(path, opts, cb) | ||
} | ||
var timer = setTimeout(retry, 100) | ||
} | ||
@@ -298,4 +310,4 @@ | ||
debug('retryThrow', path, opts, newRT) | ||
var opts_ = Object.create(opts, { retries: { value: newRT }}) | ||
return exports.lockSync(path, opts_) | ||
opts.retries = newRT | ||
return exports.lockSync(path, opts) | ||
} | ||
@@ -302,0 +314,0 @@ throw er |
{ | ||
"name": "lockfile", | ||
"version": "0.4.3", | ||
"version": "1.0.0", | ||
"main": "lockfile.js", | ||
@@ -5,0 +5,0 @@ "directories": { |
@@ -67,6 +67,11 @@ # lockfile | ||
A number of milliseconds to wait for locks to expire before giving up. | ||
Only used by lockFile.lock. Relies on fs.watch. If the lock is not | ||
cleared by the time the wait expires, then it returns with the original | ||
error. | ||
Only used by lockFile.lock. Poll for `opts.wait` ms. If the lock is | ||
not cleared by the time the wait expires, then it returns with the | ||
original error. | ||
### opts.pollPeriod | ||
When using `opts.wait`, this is the period in ms in which it polls to | ||
check if the lock has expired. Defaults to `100`. | ||
### opts.stale | ||
@@ -73,0 +78,0 @@ |
@@ -7,2 +7,7 @@ var test = require('tap').test | ||
// On Unix systems, it uses ctime by default for staleness checks, since it's | ||
// the most reliable. However, because this test artificially sets some locks | ||
// to an earlier time to simulate staleness, we use mtime here. | ||
lockFile.filetime = 'mtime' | ||
test('setup', function (t) { | ||
@@ -131,17 +136,17 @@ try { lockFile.unlockSync('basic-lock') } catch (er) {} | ||
// simulate 2s old | ||
touch.sync('stale-lock', { time: new Date(Date.now() - 2000) }) | ||
var opts = { stale: 1 } | ||
setTimeout(next, 1000) | ||
function next () { | ||
lockFile.check('stale-lock', opts, function (er, locked) { | ||
lockFile.check('stale-lock', opts, function (er, locked) { | ||
if (er) throw er | ||
t.notOk(locked) | ||
lockFile.lock('stale-lock', opts, function (er) { | ||
if (er) throw er | ||
t.notOk(locked) | ||
lockFile.lock('stale-lock', opts, function (er) { | ||
lockFile.unlock('stale-lock', function (er) { | ||
if (er) throw er | ||
lockFile.unlock('stale-lock', function (er) { | ||
if (er) throw er | ||
t.end() | ||
}) | ||
t.end() | ||
}) | ||
}) | ||
} | ||
}) | ||
}) | ||
@@ -153,11 +158,10 @@ }) | ||
lockFile.lockSync('stale-lock') | ||
setTimeout(next, 1000) | ||
function next () { | ||
var locked | ||
locked = lockFile.checkSync('stale-lock', opts) | ||
t.notOk(locked) | ||
lockFile.lockSync('stale-lock', opts) | ||
lockFile.unlockSync('stale-lock') | ||
t.end() | ||
} | ||
// simulate 2s old | ||
touch.sync('stale-lock', { time: new Date(Date.now() - 2000) }) | ||
var locked | ||
locked = lockFile.checkSync('stale-lock', opts) | ||
t.notOk(locked) | ||
lockFile.lockSync('stale-lock', opts) | ||
lockFile.unlockSync('stale-lock') | ||
t.end() | ||
}) | ||
@@ -244,3 +248,3 @@ | ||
// try to get another lock. this must fail! | ||
var opt = { stale: 1000, wait: 2000 } | ||
var opt = { stale: 1000, wait: 2000, pollInterval: 1000 } | ||
lockFile.lock('stale-wait-lock', opt, function (er) { | ||
@@ -263,17 +267,16 @@ if (!er) | ||
lockFile.lockSync('stale-windows-lock') | ||
setTimeout(next, 2000) | ||
function next () { | ||
var locked | ||
lockFile.unlockSync('stale-windows-lock') | ||
lockFile.lockSync('stale-windows-lock', opts) | ||
locked = lockFile.checkSync('stale-windows-lock', opts) | ||
t.ok(locked, "should be locked and not stale") | ||
lockFile.lock('stale-windows-lock', opts, function (er) { | ||
if (!er) | ||
t.fail('got second lock? impossible, windows file tunneling problem!') | ||
else | ||
t.pass('second lock failed, windows file tunneling problem fixed') | ||
t.end() | ||
}) | ||
} | ||
touch.sync('stale-windows-lock', { time: new Date(Date.now() - 3000) }) | ||
var locked | ||
lockFile.unlockSync('stale-windows-lock') | ||
lockFile.lockSync('stale-windows-lock', opts) | ||
locked = lockFile.checkSync('stale-windows-lock', opts) | ||
t.ok(locked, "should be locked and not stale") | ||
lockFile.lock('stale-windows-lock', opts, function (er) { | ||
if (!er) | ||
t.fail('got second lock? impossible, windows file tunneling problem!') | ||
else | ||
t.pass('second lock failed, windows file tunneling problem fixed') | ||
t.end() | ||
}) | ||
}) | ||
@@ -291,5 +294,5 @@ | ||
try { lockFile.unlockSync('stale-wait-lock') } catch (er) {} | ||
try { lockFile.unlockSync('stale-windows-lock') } catch (er) {} | ||
try { lockFile.unlockSync('stale-windows-lock') } catch (er) {} | ||
t.end() | ||
}) | ||
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
24634
667
1
87
9
5