Permalink
Browse files

s/lock-file/lockfile/

  • Loading branch information...
1 parent 3f2a647 commit 3d139b204b10c48ed13d30443a8cf6d092ea1a4c @isaacs isaacs committed Jun 27, 2012
View
@@ -73,7 +73,7 @@ var mkdir = require("mkdirp")
, fileCompletion = require("./utils/completion/file-completion.js")
, url = require("url")
, chownr = require("chownr")
- , lockFile = require("lock-file")
+ , lockFile = require("lockfile")
, crypto = require("crypto")
cache.usage = "npm cache add <tarball file>"
@@ -1,36 +0,0 @@
-{
- "name": "lock-file",
- "version": "0.0.2",
- "main": "lock-file.js",
- "directories": {
- "test": "test"
- },
- "dependencies": {},
- "devDependencies": {
- "tap": "~0.2.5"
- },
- "scripts": {
- "test": "tap test/*.js"
- },
- "repository": {
- "type": "git",
- "url": "git://github.com/isaacs/lock-file"
- },
- "keywords": [
- "lockfile",
- "lock",
- "file",
- "fs",
- "O_EXCL"
- ],
- "author": {
- "name": "Isaac Z. Schlueter",
- "email": "i@izs.me",
- "url": "http://blog.izs.me/"
- },
- "license": "BSD",
- "description": "A very polite lock file utility, which endeavors to not litter, and to wait patiently for others.",
- "readme": "# lock-file\n\nA very polite lock file utility, which endeavors to not litter, and to\nwait patiently for others.\n\n## Usage\n\n```javascript\nvar lockFile = require('lock-file')\n\n// opts is optional, and defaults to {}\nlockFile.lock('some-file.lock', opts, function (er, fd) {\n // if the er happens, then it failed to acquire a lock.\n // if there was not an error, then the fd is opened in\n // wx mode. If you want to write something to it, go ahead.\n\n // do my stuff, free of interruptions\n // then, some time later, do:\n lockFile.unlock('some-file.lock', function (er) {\n // er means that an error happened, and is probably bad.\n })\n})\n```\n\n## Methods\n\nSync methods return the value/throw the error, others don't. Standard\nnode fs stuff.\n\nAll known locks are removed when the process exits. Of course, it's\npossible for certain types of failures to cause this to fail, but a best\neffort is made to not be a litterbug.\n\n### lockFile.lock(path, [opts], cb)\n\nAcquire a file lock on the specified path. Returns the FD.\n\n### lockFile.lockSync(path, [opts])\n\nAcquire a file lock on the specified path\n\n### lockFile.unlock(path, cb)\n\nClose and unlink the lockfile.\n\n### lockFile.unlockSync(path)\n\nClose and unlink the lockfile.\n\n### lockFile.check(path, [opts], cb)\n\nCheck if the lockfile is locked and not stale.\n\nReturns boolean.\n\n### lockFile.checkSync(path, [opts], cb)\n\nCheck if the lockfile is locked and not stale.\n\nCallback is called with `cb(error, isLocked)`.\n\n## Options\n\n### opts.wait\n\nA number of milliseconds to wait for locks to expire before giving up.\nOnly used by lockFile.lock. Relies on fs.watch. If the lock is not\ncleared by the time the wait expires, then it returns with the original\nerror.\n\n### opts.stale\n\nA number of milliseconds before locks are considered to have expired.\n\n### opts.retries\n\nUsed by lock and lockSync. Retry `n` number of times before giving up.\n\n### opts.retryWait\n\nUsed by lock. Wait `n` milliseconds before retrying.\n",
- "_id": "lock-file@0.0.2",
- "_from": "lock-file@0"
-}
File renamed without changes.
@@ -1,12 +1,12 @@
-# lock-file
+# lockfile
A very polite lock file utility, which endeavors to not litter, and to
wait patiently for others.
## Usage
```javascript
-var lockFile = require('lock-file')
+var lockFile = require('lockfile')
// opts is optional, and defaults to {}
lockFile.lock('some-file.lock', opts, function (er, fd) {
@@ -137,6 +137,16 @@ exports.lock = function (path, opts, cb) {
// someone's got this one. see if it's valid.
if (opts.stale) fs.stat(path, function (er, st) {
+ if (er) {
+ if (er.code === 'ENOENT') {
+ // expired already!
+ var opts_ = Object.create(opts, { stale: { value: false }})
+ exports.lock(path, opts_, cb)
+ return
+ }
+ return cb(er)
+ }
+
var age = Date.now() - st.ctime.getTime()
if (age > opts.stale) {
exports.unlock(path, function (er) {
@@ -154,17 +164,35 @@ function notStale (er, path, opts, cb) {
if (typeof opts.wait === 'number' && opts.wait > 0) {
// wait for some ms for the lock to clear
var start = Date.now()
- var watcher = fs.watch(path, function (change) {
- if (change === 'rename') {
- // ok, try and get it now.
- // if this fails, then continue waiting, maybe.
- watcher.close()
- clearTimeout(timer)
- var newWait = Date.now() - start
- var opts_ = Object.create(opts, { wait: { value: newWait }})
- exports.lock(path, opts_, cb)
- }
- })
+
+ var retried = false
+ function retry () {
+ if (retried) return
+ retried = true
+ // maybe already closed.
+ try { watcher.close() } catch (e) {}
+ clearTimeout(timer)
+ var newWait = Date.now() - start
+ var opts_ = Object.create(opts, { wait: { value: newWait }})
+ exports.lock(path, opts_, cb)
+ }
+
+ try {
+ var watcher = fs.watch(path, function (change) {
+ if (change === 'rename') {
+ // ok, try and get it now.
+ // if this fails, then continue waiting, maybe.
+ retry()
+ }
+ })
+ watcher.on('error', function (er) {
+ // usually means it expired before the watcher spotted it
+ retry()
+ })
+ } catch (er) {
+ retry()
+ }
+
var timer = setTimeout(function () {
watcher.close()
cb(er)
@@ -0,0 +1,39 @@
+{
+ "name": "lockfile",
+ "version": "0.2.0",
+ "main": "lockfile.js",
+ "directories": {
+ "test": "test"
+ },
+ "dependencies": {},
+ "devDependencies": {
+ "tap": "~0.2.5"
+ },
+ "scripts": {
+ "test": "tap test/*.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/lockfile"
+ },
+ "keywords": [
+ "lockfile",
+ "lock",
+ "file",
+ "fs",
+ "O_EXCL"
+ ],
+ "author": {
+ "name": "Isaac Z. Schlueter",
+ "email": "i@izs.me",
+ "url": "http://blog.izs.me/"
+ },
+ "license": "BSD",
+ "description": "A very polite lock file utility, which endeavors to not litter, and to wait patiently for others.",
+ "readme": "# lockfile\n\nA very polite lock file utility, which endeavors to not litter, and to\nwait patiently for others.\n\n## Usage\n\n```javascript\nvar lockFile = require('lockfile')\n\n// opts is optional, and defaults to {}\nlockFile.lock('some-file.lock', opts, function (er, fd) {\n // if the er happens, then it failed to acquire a lock.\n // if there was not an error, then the fd is opened in\n // wx mode. If you want to write something to it, go ahead.\n\n // do my stuff, free of interruptions\n // then, some time later, do:\n lockFile.unlock('some-file.lock', function (er) {\n // er means that an error happened, and is probably bad.\n })\n})\n```\n\n## Methods\n\nSync methods return the value/throw the error, others don't. Standard\nnode fs stuff.\n\nAll known locks are removed when the process exits. Of course, it's\npossible for certain types of failures to cause this to fail, but a best\neffort is made to not be a litterbug.\n\n### lockFile.lock(path, [opts], cb)\n\nAcquire a file lock on the specified path. Returns the FD.\n\n### lockFile.lockSync(path, [opts])\n\nAcquire a file lock on the specified path\n\n### lockFile.unlock(path, cb)\n\nClose and unlink the lockfile.\n\n### lockFile.unlockSync(path)\n\nClose and unlink the lockfile.\n\n### lockFile.check(path, [opts], cb)\n\nCheck if the lockfile is locked and not stale.\n\nReturns boolean.\n\n### lockFile.checkSync(path, [opts], cb)\n\nCheck if the lockfile is locked and not stale.\n\nCallback is called with `cb(error, isLocked)`.\n\n## Options\n\n### opts.wait\n\nA number of milliseconds to wait for locks to expire before giving up.\nOnly used by lockFile.lock. Relies on fs.watch. If the lock is not\ncleared by the time the wait expires, then it returns with the original\nerror.\n\n### opts.stale\n\nA number of milliseconds before locks are considered to have expired.\n\n### opts.retries\n\nUsed by lock and lockSync. Retry `n` number of times before giving up.\n\n### opts.retryWait\n\nUsed by lock. Wait `n` milliseconds before retrying.\n",
+ "_id": "lockfile@0.2.0",
+ "dist": {
+ "shasum": "1c4090b1c45ac45ed6898025c9e5d1e53fa93813"
+ },
+ "_from": "../lockfile"
+}
@@ -1,5 +1,5 @@
var test = require('tap').test
-var lockFile = require('../lock-file.js')
+var lockFile = require('../lockfile.js')
var path = require('path')
var fs = require('fs')
@@ -1,4 +1,4 @@
-var lockFile = require('../../lock-file.js')
+var lockFile = require('../../lockfile.js')
lockFile.lockSync('never-forget')
@@ -1,3 +1,3 @@
-var lockFile = require('../../lock-file.js')
+var lockFile = require('../../lockfile.js')
lockFile.lock('never-forget', function () {})
View
@@ -66,7 +66,7 @@
"glob": "~3.1.9",
"init-package-json": "0",
"osenv": "0",
- "lock-file": "0"
+ "lockfile": ">=0.2"
},
"bundleDependencies": [
"semver",
@@ -101,7 +101,7 @@
"glob",
"init-package-json",
"osenv",
- "lock-file"
+ "lockfile"
],
"devDependencies": {
"ronn": "https://github.com/isaacs/ronnjs/tarball/master",

0 comments on commit 3d139b2

Please sign in to comment.