Description
The debounce loop in file_watcher.rs accumulates all pending events in an unbounded HashMap. Under git checkout of a large branch or bulk file generation, tens of thousands of events can arrive before the 100 ms debounce window closes. compute_changes then iterates all pending entries against all LSP registration globs at O(pending × registrations × patterns).
Additionally, NEVER_FORWARD_COMPONENTS excludes .git and target but not vendor/, third_party/, node_modules/, or other large dependency trees, so projects using those layouts can trigger the pathological case.
Reproduction Steps
- Configure mcpls for a large monorepo with
vendor/ directory
- Run
git checkout switching to a branch with significant vendored changes
- Observe: memory spike during the 100 ms debounce window; potential multi-second stall in
compute_changes
Expected Behavior
The watcher should shed excess events gracefully rather than buffering without limit.
Actual Behavior
pending HashMap grows without bound until the debounce fires.
Affected Code
crates/mcpls-core/src/lsp/file_watcher.rs — debounce accumulator, line ~352
NEVER_FORWARD_COMPONENTS filter list
Fix Direction
- Cap
pending at a reasonable limit (e.g. 10 000 entries); on overflow, emit a single synthetic "invalidate all" event rather than tracking individual paths.
- Extend
NEVER_FORWARD_COMPONENTS to include vendor, node_modules, third_party.
Environment
- Affects large monorepos or projects with vendored dependencies
- Severity: low for typical projects, high for monorepos
Description
The debounce loop in
file_watcher.rsaccumulates all pending events in an unboundedHashMap. Undergit checkoutof a large branch or bulk file generation, tens of thousands of events can arrive before the 100 ms debounce window closes.compute_changesthen iterates all pending entries against all LSP registration globs atO(pending × registrations × patterns).Additionally,
NEVER_FORWARD_COMPONENTSexcludes.gitandtargetbut notvendor/,third_party/,node_modules/, or other large dependency trees, so projects using those layouts can trigger the pathological case.Reproduction Steps
vendor/directorygit checkoutswitching to a branch with significant vendored changescompute_changesExpected Behavior
The watcher should shed excess events gracefully rather than buffering without limit.
Actual Behavior
pendingHashMap grows without bound until the debounce fires.Affected Code
crates/mcpls-core/src/lsp/file_watcher.rs— debounce accumulator, line ~352NEVER_FORWARD_COMPONENTSfilter listFix Direction
pendingat a reasonable limit (e.g. 10 000 entries); on overflow, emit a single synthetic "invalidate all" event rather than tracking individual paths.NEVER_FORWARD_COMPONENTSto includevendor,node_modules,third_party.Environment