Skip to main content

Module FileWatcherProvider

Module FileWatcherProvider 

Source
Expand description

§FileWatcherProvider (Environment)

Backing implementation of FileWatcherProvider for MountainEnvironment.

Native filesystem notifications are delegated to the notify crate, which picks up inotify on Linux, FSEvents on macOS, and ReadDirectoryChangesW on Windows. Events from the watcher thread flow through an unbounded channel into a tokio task that forwards them back to Cocoon over the reverse-RPC channel as $fileWatcher:event notifications.

§Concurrency notes

  • notify::recommended_watcher executes callbacks on its own native thread, so we tunnel events through a bounded channel before touching async code. The forwarder task is spawned once on first registration and lives for the entire process lifetime.
  • macOS FSEvents may emit duplicate Create/Change events for the same path in very short succession. We debounce by path within a 100 ms window per-handle, keyed on (handle, path, kind).
  • Linux inotify has a small per-user watcher cap (fs.inotify.max_user_watches); hitting it surfaces as notify::Error::MaxFilesWatch. We propagate that verbatim to the caller so the UI can show a guidance message.

Structs§

WatcherEntry
Internal entry tracked per registered watcher. The Watcher handle must be kept alive for the lifetime of the registration; dropping it releases the OS resources.
WatcherState
Lazily-initialised process-wide state for file watching. Instances of the event-forwarder task are singletons keyed on the MountainEnvironment handle. Access through WatcherState::Get.

Constants§

DebounceWindow 🔒
Interval below which a second (path, kind) event for the same handle is ignored. Tuned for FSEvents coalescing.

Functions§

CompileGlobToRegex 🔒
Translate a VS Code glob pattern into a regex::Regex so the native watcher can apply the caller’s filter before paying for an IPC hop. A small subset of the glob grammar is supported (**, *, ?, […], {…,…} alternation) - exactly what TypeScript-language-features and the other ship-time extensions rely on.
MapEventKind 🔒

Type Aliases§

DedupKey 🔒
Composite key used to detect duplicate watcher registrations. Two extensions (or the same extension activated twice) frequently register the same (root, recursive, pattern) triple within milliseconds of each other - the typescript-language-features and git extensions are the worst offenders. Without dedup, each registration spawns its own notify::Watcher with its own kqueue/inotify subscription tree, doubling (or worse) FS-event traffic and burning kernel handles.