Skip to content

Commit 561ce62

Browse files
committed
Run Windows directory watcher in an isolate.
1 parent e0cc0bc commit 561ce62

File tree

7 files changed

+762
-544
lines changed

7 files changed

+762
-544
lines changed

pkgs/watcher/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 1.1.5-wip
22

3+
- `DirectoryWatcher` on Windows watches in a separate Isolate to make buffer
4+
exhaustion, "Directory watcher closed unexpectedly", much less likely. The old
5+
implementation which does not use a separate Isolate is available as
6+
`DirectoryWatcher(path, runInIsolateOnWindows: false)`.
37
- Polling watchers now check file sizes as well as "last modified" times, so
48
they are less likely to miss changes on platforms with low resolution
59
timestamps.

pkgs/watcher/lib/src/directory_watcher.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import 'directory_watcher/windows.dart';
2020
/// the message "Directory watcher closed unexpectedly" on the event stream. The
2121
/// code using the watcher needs to do additional work to account for the
2222
/// dropped events, for example by recomputing interesting files from scratch.
23+
/// By default, the watcher is started in a separate isolate to make this less
24+
/// likely. Pass `runInIsolateOnWindows = false` to not launch an isolate.
2325
abstract class DirectoryWatcher implements Watcher {
2426
/// The directory whose contents are being monitored.
2527
@Deprecated('Expires in 1.0.0. Use DirectoryWatcher.path instead.')
@@ -35,7 +37,11 @@ abstract class DirectoryWatcher implements Watcher {
3537
/// shorter will give more immediate feedback at the expense of doing more IO
3638
/// and higher CPU usage. Defaults to one second. Ignored for non-polling
3739
/// watchers.
38-
factory DirectoryWatcher(String directory, {Duration? pollingDelay}) {
40+
///
41+
/// On Windows, pass [runInIsolateOnWindows] `false` to not run the watcher
42+
/// in a separate isolate to reduce buffer exhaustion failures.
43+
factory DirectoryWatcher(String directory,
44+
{Duration? pollingDelay, bool runInIsolateOnWindows = true}) {
3945
if (FileSystemEntity.isWatchSupported) {
4046
var customWatcher = createCustomDirectoryWatcher(
4147
directory,
@@ -44,7 +50,10 @@ abstract class DirectoryWatcher implements Watcher {
4450
if (customWatcher != null) return customWatcher;
4551
if (Platform.isLinux) return LinuxDirectoryWatcher(directory);
4652
if (Platform.isMacOS) return MacOSDirectoryWatcher(directory);
47-
if (Platform.isWindows) return WindowsDirectoryWatcher(directory);
53+
if (Platform.isWindows) {
54+
return WindowsDirectoryWatcher(directory,
55+
runInIsolate: runInIsolateOnWindows);
56+
}
4857
}
4958
return PollingDirectoryWatcher(directory, pollingDelay: pollingDelay);
5059
}

0 commit comments

Comments
 (0)