Revert watcher changes for mac. We ended up with a 1.6 dependency, which I don't know if is a good idea or not. Revert "Mac no longer fire bogus events. Fix Mac watcher." Revert "Don't use kFSEventStreamCreateFlagNoDefer as it messes with event flushing." BUG= Review URL: https://codereview.chromium.org//325963005 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/watcher@37173 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/watcher/lib/src/directory_watcher/mac_os.dart b/pkgs/watcher/lib/src/directory_watcher/mac_os.dart index 65f07fa..e3efa2d 100644 --- a/pkgs/watcher/lib/src/directory_watcher/mac_os.dart +++ b/pkgs/watcher/lib/src/directory_watcher/mac_os.dart
@@ -73,15 +73,30 @@ /// a subdirectory that was moved into the watched directory. StreamSubscription<FileSystemEntity> _listSubscription; + /// The timer for tracking how long we wait for an initial batch of bogus + /// events (see issue 14373). + Timer _bogusEventTimer; + _MacOSDirectoryWatcher(String directory, int parentId) : directory = directory, _files = new PathSet(directory), _id = "$parentId/${_count++}" { - _listDir().then((_) { - if (MacOSDirectoryWatcher.logDebugInfo) { - print("[$_id] finished initial directory list"); - } - _startWatch(); + _startWatch(); + + // Before we're ready to emit events, wait for [_listDir] to complete and + // for enough time to elapse that if bogus events (issue 14373) would be + // emitted, they will be. + // + // If we do receive a batch of events, [_onBatch] will ensure that these + // futures don't fire and that the directory is re-listed. + Future.wait([ + _listDir().then((_) { + if (MacOSDirectoryWatcher.logDebugInfo) { + print("[$_id] finished initial directory list"); + } + }), + _waitForBogusEvents() + ]).then((_) { if (MacOSDirectoryWatcher.logDebugInfo) { print("[$_id] watcher is ready, known files:"); for (var file in _files.toSet()) { @@ -119,6 +134,29 @@ } } + // If we get a batch of events before we're ready to begin emitting events, + // it's probable that it's a batch of pre-watcher events (see issue 14373). + // Ignore those events and re-list the directory. + if (!isReady) { + if (MacOSDirectoryWatcher.logDebugInfo) { + print("[$_id] not ready to emit events, re-listing directory"); + } + + // Cancel the timer because bogus events only occur in the first batch, so + // we can fire [ready] as soon as we're done listing the directory. + _bogusEventTimer.cancel(); + _listDir().then((_) { + if (MacOSDirectoryWatcher.logDebugInfo) { + print("[$_id] watcher is ready, known files:"); + for (var file in _files.toSet()) { + print("[$_id] ${p.relative(file, from: directory)}"); + } + } + _readyCompleter.complete(); + }); + return; + } + _sortEvents(batch).forEach((path, events) { var relativePath = p.relative(path, from: directory); if (MacOSDirectoryWatcher.logDebugInfo) { @@ -354,6 +392,17 @@ _watchSubscription = null; + // If the directory still exists and we're still expecting bogus events, + // this is probably issue 14849 rather than a real close event. We should + // just restart the watcher. + if (!isReady && new Directory(directory).existsSync()) { + if (MacOSDirectoryWatcher.logDebugInfo) { + print("[$_id] fake closure (issue 14849), re-opening stream"); + } + _startWatch(); + return; + } + // FSEvents can fail to report the contents of the directory being removed // when the directory itself is removed, so we need to manually mark the // files as removed. @@ -393,6 +442,19 @@ return completer.future; } + /// Wait 200ms for a batch of bogus events (issue 14373) to come in. + /// + /// 200ms is short in terms of human interaction, but longer than any Mac OS + /// watcher tests take on the bots, so it should be safe to assume that any + /// bogus events will be signaled in that time frame. + Future _waitForBogusEvents() { + var completer = new Completer(); + _bogusEventTimer = new Timer( + new Duration(milliseconds: 200), + completer.complete); + return completer.future; + } + /// Emit an event with the given [type] and [path]. void _emitEvent(ChangeType type, String path) { if (!isReady) return;
diff --git a/pkgs/watcher/pubspec.yaml b/pkgs/watcher/pubspec.yaml index adf8ddb..51ba562 100644 --- a/pkgs/watcher/pubspec.yaml +++ b/pkgs/watcher/pubspec.yaml
@@ -1,5 +1,5 @@ name: watcher -version: 0.9.4-dev +version: 0.9.3-dev author: "Dart Team <misc@dartlang.org>" homepage: http://www.dartlang.org description: > @@ -12,4 +12,4 @@ scheduled_test: ">=0.9.3-dev <0.11.0" unittest: ">=0.9.2 <0.10.0" environment: - sdk: ">=1.6.0 <2.0.0" + sdk: ">=0.8.10+6 <2.0.0"