Skip to content

Commit

Permalink
Ensure 500 ms of directory watch downtime.
Browse files Browse the repository at this point in the history
Should help with meteor#1506.

Fingers crossed for an eventual usable fs.watch.
  • Loading branch information
glasser authored and avital committed Nov 1, 2013
1 parent 11a1042 commit 7e39e8c
Showing 1 changed file with 20 additions and 26 deletions.
46 changes: 20 additions & 26 deletions tools/watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var fiberHelpers = require('./fiber-helpers.js');
//
// In a directory watch, you provide an absolute path to a directory,
// two lists of regular expressions specifying the entries to
// include and exclude, and an array of which entries to expect
// include and exclude, and an array of which entries to expect.
//
// For directory watches, the regular expressions work as follows. You provide
// two arrays of regular expressions, an include list and an exclude list. An
Expand Down Expand Up @@ -275,7 +275,6 @@ var Watcher = function (options) {
self.justCheckOnce = !!options._justCheckOnce;

self.fileWatches = []; // array of paths
self.directoryWatches = []; // array of interval handles

// We track all of the currently active timers so that we can cancel
// them at stop() time. This stops the process from hanging at
Expand All @@ -292,7 +291,7 @@ var Watcher = function (options) {
}

self._startFileWatches();
self._startDirectoryWatches();
self._checkDirectories();
};

_.extend(Watcher.prototype, {
Expand Down Expand Up @@ -403,7 +402,7 @@ _.extend(Watcher.prototype, {
}, 1000);
},

_startDirectoryWatches: function () {
_checkDirectories: function (yielding) {
var self = this;

// fs.watchFile doesn't work for directories (as tested on ubuntu)
Expand All @@ -413,31 +412,32 @@ _.extend(Watcher.prototype, {
// https://github.com/joyent/node/issues/5463
// https://github.com/joyent/libuv/commit/38df93cf
//
// Instead, just use setInterval. _fireIfDirectoryChanged already
// does checking to see if anything really changed. When node has a
// stable directory watching API that is more efficient than just
// polling, look at the history for this file around release 0.6.5
// for a version that uses fs.watch.
// Instead, just check periodically with setTimeout. (We use setTimeout to
// ensure that there is a 500 ms pause between the *end* of one poll cycle
// and the *beginning* of another instead of using setInterval which still
// can lead to permanent 100% CPU usage.) When node has a stable directory
// watching API that is more efficient than just polling, look at the
// history for this file around release 0.6.5 for a version that uses
// fs.watch.

if (self.stopped)
return;

_.each(self.watchSet.directories, function (info) {
if (self.stopped)
return;

// Check for the case where by the time we created the watch, the
// directory has already changed.
if (self._fireIfDirectoryChanged(info))
return;

if (self.stopped || self.justCheckOnce)
if (self._fireIfDirectoryChanged(info, yielding))
return;

// Notice that we poll very frequently (500 ms)
self.directoryWatches.push(
setInterval(fiberHelpers.inFiber(function () {
self._fireIfDirectoryChanged(info, true);
}), 500)
);
});

if (!self.stopped && !self.justCheckOnce) {
setTimeout(fiberHelpers.inFiber(function () {
self._checkDirectories(true);
}), 500);
}
},

_fire: function () {
Expand Down Expand Up @@ -465,12 +465,6 @@ _.extend(Watcher.prototype, {
fs.unwatchFile(absPath);
});
self.fileWatches = [];

// Clean up directory watches
_.each(self.directoryWatches, function (watch) {
clearInterval(watch);
});
self.directoryWatches = [];
}
});

Expand Down

0 comments on commit 7e39e8c

Please sign in to comment.