Skip to content

fix(@angular/build): coalesce external watcher directories to avoid macOS FSEvents limit - #34347

Open
clydin wants to merge 1 commit into
angular:mainfrom
clydin:fix/external-watcher-fsevents-limit
Open

clydin wants to merge 1 commit into
angular:mainfrom
clydin:fix/external-watcher-fsevents-limit

Conversation

@clydin

@clydin clydin commented Oct 14, 2026

Copy link
Copy Markdown
Member

Previously, ParcelExternalManager immediately created a separate @parcel/watcher subscription for the parent directory of every watched file outside the workspace root. In monorepo setups where an application imports from hundreds of external library directories and hoisted node_modules packages, this exceeded macOS's ~512 per-process FSEvents stream limit, causing subsequent subscriptions to silently fail and miss file changes.

To prevent exhausting native watcher streams, ParcelExternalManager now normalizes external node_modules file paths to their package root directory and batches synchronous file additions and removals within a microtask so nested child directories are subsumed before subscribing. When the number of external target directories exceeds the subscription budget of 256, a prefix tree is used to iteratively collapse the deepest branching subdirectories into common ancestors while preferring directories that do not contain workspaceRoot. Additionally, if parcelWatcher.subscribe() rejects for an existing directory on disk, the manager dynamically lowers its subscription budget and re-reconciles into higher-level ancestor directories.

Closes #34246

…acOS FSEvents limit

Previously, `ParcelExternalManager` immediately created a separate `@parcel/watcher` subscription for the parent directory of every watched file outside the workspace root. In monorepo setups where an application imports from hundreds of external library directories and hoisted `node_modules` packages, this exceeded macOS's ~512 per-process `FSEvents` stream limit, causing subsequent subscriptions to silently fail and miss file changes.

To prevent exhausting native watcher streams, `ParcelExternalManager` now normalizes external `node_modules` file paths to their package root directory and batches synchronous file additions and removals within a microtask so nested child directories are subsumed before subscribing. When the number of external target directories exceeds the subscription budget of 256, a prefix tree is used to iteratively collapse the deepest branching subdirectories into common ancestors while preferring directories that do not contain `workspaceRoot`. Additionally, if `parcelWatcher.subscribe()` rejects for an existing directory on disk, the manager dynamically lowers its subscription budget and re-reconciles into higher-level ancestor directories.

Closes angular#34246
@clydin
clydin force-pushed the fix/external-watcher-fsevents-limit branch from b903d5f to cf1f3a3 Compare October 15, 2026 02:09
@clydin
clydin marked this pull request as ready for review October 15, 2026 02:09
@clydin clydin added the target: patch This PR is targeted for the next patch release label Oct 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the ParcelExternalManager in the Angular build package to optimize directory subscriptions when using @parcel/watcher. It introduces a directory prefix tree (trie) to coalesce multiple external directory subscriptions into common ancestors when the subscription count exceeds a budget (defaulting to 256), preventing macOS FSEvents stream limit errors. Additionally, it adds comprehensive unit tests to verify batching, path normalization, coalescing logic, and dynamic budget reduction. There are no review comments, and the changes look solid and well-tested.

@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Oct 15, 2026
@clydin
clydin requested a review from alan-agius4 October 15, 2026 02:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: review The PR is still awaiting reviews from at least one requested reviewer area: @angular/build target: patch This PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dev-server on macOS misses changes outside the workspace root: one FSEvents stream per external directory exceeds the per-process limit

1 participant