-
-
Save isaacs/1131136 to your computer and use it in GitHub Desktop.
rimraf with futures
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module.exports = rimraf | |
var path = require("path") | |
, fs = require("fs") | |
// for EBUSY handling | |
var waitBusy = {} | |
// for EMFILE handling | |
var resetTimer = null | |
, timeout = 0 | |
function rimraf (p, opt, cb_) { | |
if (typeof cb_ !== "function") cb_ = opt, opt = {} | |
opt.maxBusyTries = opt.maxBusyTries || 3 | |
rimraf_(p, function cb (er) { | |
if (er) { | |
if (er.message.match(/^EBUSY/)) { | |
// windows is annoying. | |
if (!waitBusy.hasOwnProperty(p)) waitBusy[p] = opt.maxBusyTries | |
if (waitBusy[p]) { | |
waitBusy[p] -- | |
// give it 100ms more each time | |
var time = (opt.maxBusyTries - waitBusy[p]) * 100 | |
return setTimeout(function () { rimraf_(p, cb) }, time) | |
} | |
} | |
if (er.message.match(/^EMFILE/)) { | |
setTimeout(function () { | |
rimraf_(p, cb) | |
}, timeout ++) | |
return | |
} | |
} | |
timeout = 0 | |
cb_(er) | |
}) | |
} | |
function rimraf_ (p, cb) { | |
fs.lstat(p, function (er, s) { | |
if (er) return cb() | |
if (!s.isDirectory()) return fs.unlink(p, cb) | |
fs.readdir(p, function (er, files) { | |
if (er) return cb(er) | |
asyncForEach(files.map(function (f) { | |
return path.join(p, f) | |
}), function (f, cb) { | |
rimraf(f, opt, cb) | |
}, function (er) { | |
if (er) return cb(er) | |
fs.rmdir(p, cb) | |
}) | |
}) | |
}) | |
} | |
// this is the flow control util | |
function asyncForEach (list, fn, cb) { | |
if (!list.length) cb() | |
var c = list.length | |
, errState = null | |
list.forEach(function (item, i, list) { | |
fn(item, function (er) { | |
if (errState) return | |
if (er) return cb(errState = er) | |
if (-- c === 0) return cb() | |
}) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var path = require('path'), | |
fs = require('fs'), | |
Future = require('fibers/future'); | |
// Create future-returning fs functions | |
var fs2 = {}; | |
for (var ii in fs) { | |
fs2[ii] = Future.wrap(fs[ii]); | |
} | |
// Return a future which just pauses for a certain amount of time | |
function timer(ms) { | |
var future = new Future; | |
setTimeout(function() { | |
future.return(); | |
}, ms); | |
return future; | |
} | |
var timeout = 0; | |
var rimraf = module.exports = function(p, opts) { | |
opts = opts || {}; | |
opts.maxBusyTries = opts.maxBusyTries || 3; | |
var busyTries = 0; | |
while (true) { | |
try { | |
try { | |
var stat = fs2.lstat(p).wait(); | |
} catch (ex) { | |
continue; | |
} | |
if (!stat.isDirectory()) return fs2.unlink(p).wait(); | |
var rimrafs = fs2.readdir(p).wait().map(function(file) { | |
return rimraf(path.join(p, file), opts); | |
}); | |
Future.wait(rimrafs); | |
fs2.rmdir(p).wait(); | |
timeout = 0; | |
return; | |
} catch (ex) { | |
if (ex.message.match(/^EMFILE/)) { | |
timer(timeout += 10).wait(); | |
} else if (ex.message.match(/^EBUSY/) && busyTries < opt.maxBusyTries) { | |
timer(++busyTries * 100).wait(); | |
} else { | |
throw ex; | |
} | |
} | |
} | |
}.future(); |
Oh yeah go ahead MIT is fine!
…On 2011/08/08, at 13:21, isaacs ***@***.*** wrote:
Oh, I should have asked already, but can I assume you have no problem including this in the rimraf repo under the MIT license?
##
Reply to this email directly or view it on GitHub:
https://gist.github.com/1131136
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Oh, I should have asked already, but can I assume you have no problem including this in the rimraf repo under the MIT license?