Skip to content

fix(repo_metadata): cache failed-walk paths and exclude Windows system dirs from watcher#11448

Open
cbeaulieu-gt wants to merge 4 commits into
warpdotdev:masterfrom
cbeaulieu-gt:cbeaulieu-gt/fix-watcher-temp-dir
Open

fix(repo_metadata): cache failed-walk paths and exclude Windows system dirs from watcher#11448
cbeaulieu-gt wants to merge 4 commits into
warpdotdev:masterfrom
cbeaulieu-gt:cbeaulieu-gt/fix-watcher-temp-dir

Conversation

@cbeaulieu-gt
Copy link
Copy Markdown

Summary

Cuts sustained idle CPU on Windows when the file-tree view is rooted at the user's home directory. Two complementary mitigations:

  1. failed_walk_paths cache on LocalRepoMetadataModel short-circuits re-walks of paths that previously hit ExceededMaxFileLimit, so a single AppData\Local\Temp write doesn't trigger a full Entry::build_tree re-walk on every filesystem event.
  2. Platform-specific watcher exclude list in WatchFilter keeps known-noisy system directories (Windows: AppData\Local\Temp, AppData\Local\Microsoft\Windows, AppData\LocalLow) out of the recursive watcher entirely. Case-insensitive, component-wise match.

Closes #11349.

Companion architectural fix (cancellable in-flight walks) is tracked as #11350 and is out of scope for this PR.

Empirical verification (Windows 11)

Reproducer from the issue: file tree view rooted at %USERPROFILE%, with Office / browser / AV background activity touching AppData\Local\Temp.

Metric Before After
Sustained machine CPU (warp) 14–20% (continuous) Two brief ~4-second blips
Entry::build_tree calls Per filesystem event Cached after first Exceeded

Commits

  • c4f1001 — fix(repo_metadata): cache failed-walk paths and exclude system dirs from watcher
  • 0994217 — test(repo_metadata): pin component-aware cache short-circuit, document unbounded-cache tradeoff (regression guard against StandardizedPath::starts_with switching to byte-prefix semantics in a future typed-path upgrade — asserts cached Temp does NOT short-circuit sibling Tempest)
  • 3c27727 — test(repo_metadata): drop unused child_path binding in cache test (caught by ./script/presubmit)

Tradeoffs / known limitations

  • failed_walk_paths is unbounded. Documented in the field's doc-comment alongside the conditions under which an eviction policy would be worth adding. In practice the set is bounded by the number of distinct subtrees in the workspace that exceed MAX_FILES_PER_REPO, which is small (typically O(10) on a home-dir watch).
  • System-dir excludes are Windows-only for now. The framework is platform-conditional; Linux/macOS noisy-dir lists can be added in follow-up PRs if similar reproducers surface.
  • Does not fix the cancellation gap when the file tree view is closed mid-walk — that's Entry::build_tree walks are not cancellable — closing the file tree view leaves CPU spike running until in-flight walks finish #11350.

Test plan

  • cargo test -p repo_metadata — all green, includes the new component-aware cache test
  • ./script/presubmit — full workspace clippy + tests green
  • Manual reproducer on Windows 11: sustained CPU drops from 14–20% to two ~4s blips (table above)
  • Maintainer review of cache eviction policy (currently unbounded; documented as acceptable tradeoff)

Related


🤖 Generated by Claude Code on behalf of @cbeaulieu-gt

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 20, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @cbeaulieu-gt on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@github-actions github-actions Bot added the external-contributor Indicates that a PR has been opened by someone outside the Warp team. label May 20, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 20, 2026

@cbeaulieu-gt

I'm starting a first review of this pull request.

You can view the conversation on Warp.

I reviewed this pull request and requested human review from: @moirahuang.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

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

Overview

This PR reduces Windows file-tree watcher churn by caching paths whose subtree walk exceeded the repo file limit and by filtering known noisy Windows AppData system directories before watcher events reach repo metadata processing. The new regression tests cover cache hits, component-boundary behavior, and Windows-only system-directory filtering.

Concerns

  • The Windows system-directory filter currently matches the AppData patterns at any component position, which can drop watcher events for a legitimate project subtree with the same component sequence. This is worth tightening, but it is not blocking for the reported home-directory CPU issue.

Verdict

Found: 0 critical, 0 important, 1 suggestions

Approve with nits

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread crates/repo_metadata/src/local_model.rs
@oz-for-oss oz-for-oss Bot requested a review from moirahuang May 20, 2026 21:38
@cbeaulieu-gt
Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label May 20, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 20, 2026

The cla-bot has been summoned, and re-checked this pull request!

cbeaulieu-gt added a commit to cbeaulieu-gt/warp that referenced this pull request May 20, 2026
…ata root

Previously `is_system_dir_excluded_windows` matched the AppData pattern
anywhere in the path component list, meaning a workspace subtree like
`C:\workspace\fixtures\AppData\Local\Temp\sample.tmp` would be silently
excluded from file-tree watcher events even though it is not the user's
real system temp directory.

Addresses oz-bot suggestion on PR warpdotdev#11448 (discussion_r3277342979):
anchor the match to `%USERPROFILE%\AppData` before checking the known
noisy sub-paths (Local\Temp, Local\Microsoft\Windows, LocalLow). If
USERPROFILE is unset the function falls back to the previous unanchored
scan on a best-effort basis.

Also updates the existing Windows-only regression tests to construct
paths dynamically from the real %USERPROFILE% (the old tests used a
hardcoded `C:\Users\TestUser` path that would never match on CI) and
adds a new test `test_watch_filter_workspace_appdata_subtree_not_excluded`
covering the false-positive case: a workspace path that contains the
AppData segments as a middle component must NOT be excluded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alokedesai alokedesai requested review from alokedesai and removed request for moirahuang May 20, 2026 23:15
@moirahuang moirahuang requested review from moirahuang and removed request for moirahuang May 20, 2026 23:15
@alokedesai
Copy link
Copy Markdown
Member

Hey @cbeaulieu-gt, thanks for sending this our way. I'll take a look at this tomorrow and leave some more detailed feedback!

@cbeaulieu-gt cbeaulieu-gt force-pushed the cbeaulieu-gt/fix-watcher-temp-dir branch from 4ddfc01 to 6946f40 Compare May 21, 2026 17:29
cbeaulieu-gt added a commit to cbeaulieu-gt/warp that referenced this pull request May 21, 2026
…ata root

Previously `is_system_dir_excluded_windows` matched the AppData pattern
anywhere in the path component list, meaning a workspace subtree like
`C:\workspace\fixtures\AppData\Local\Temp\sample.tmp` would be silently
excluded from file-tree watcher events even though it is not the user's
real system temp directory.

Addresses oz-bot suggestion on PR warpdotdev#11448 (discussion_r3277342979):
anchor the match to `%USERPROFILE%\AppData` before checking the known
noisy sub-paths (Local\Temp, Local\Microsoft\Windows, LocalLow). If
USERPROFILE is unset the function falls back to the previous unanchored
scan on a best-effort basis.

Also updates the existing Windows-only regression tests to construct
paths dynamically from the real %USERPROFILE% (the old tests used a
hardcoded `C:\Users\TestUser` path that would never match on CI) and
adds a new test `test_watch_filter_workspace_appdata_subtree_not_excluded`
covering the false-positive case: a workspace path that contains the
AppData segments as a middle component must NOT be excluded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cbeaulieu-gt and others added 4 commits May 21, 2026 14:55
…rom watcher

Adds a `failed_walk_paths` cache on `LocalRepoMetadataModel` to short-circuit
re-walks of paths that previously hit `ExceededMaxFileLimit`, and extends
`WatchFilter` with a platform-specific system-dir exclude list (Windows:
AppData\Local\Temp, AppData\Local\Microsoft\Windows, AppData\LocalLow;
case-insensitive, component-wise match). Reduces CPU when the file-tree
view is rooted at the user's home directory on Windows.

Companion to warpdotdev#11350 (cancellable in-flight walks; out of scope for this PR).

fixes warpdotdev#11349
…t unbounded-cache tradeoff

Adds `test_failed_walk_cache_respects_component_boundaries` as a regression
guard against `StandardizedPath::starts_with` silently switching to byte-prefix
semantics in a future `typed-path` upgrade. Asserts that a cached `Temp` path
does NOT short-circuit a sibling `Tempest` directory.

Also expands the doc-comment on `LocalRepoMetadataModel::failed_walk_paths` to
note the unbounded-growth tradeoff and the conditions under which an eviction
policy would be worth adding.

Both changes follow up on pre-PR review feedback for warpdotdev#11349 — no behavior
change, just stronger guard rails.
Caught by `./script/presubmit` (cargo clippy --workspace --all-targets
--tests -- -D warnings) — the per-crate clippy run during initial
implementation didn't include `--tests` so the unused-variable lint
wasn't surfaced.
…ata root

Previously `is_system_dir_excluded_windows` matched the AppData pattern
anywhere in the path component list, meaning a workspace subtree like
`C:\workspace\fixtures\AppData\Local\Temp\sample.tmp` would be silently
excluded from file-tree watcher events even though it is not the user's
real system temp directory.

Addresses oz-bot suggestion on PR warpdotdev#11448 (discussion_r3277342979):
anchor the match to `%USERPROFILE%\AppData` before checking the known
noisy sub-paths (Local\Temp, Local\Microsoft\Windows, LocalLow). If
USERPROFILE is unset the function falls back to the previous unanchored
scan on a best-effort basis.

Also updates the existing Windows-only regression tests to construct
paths dynamically from the real %USERPROFILE% (the old tests used a
hardcoded `C:\Users\TestUser` path that would never match on CI) and
adds a new test `test_watch_filter_workspace_appdata_subtree_not_excluded`
covering the false-positive case: a workspace path that contains the
AppData segments as a middle component must NOT be excluded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cbeaulieu-gt cbeaulieu-gt force-pushed the cbeaulieu-gt/fix-watcher-temp-dir branch from 6946f40 to 465f391 Compare May 21, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed external-contributor Indicates that a PR has been opened by someone outside the Warp team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File tree view's recursive watcher re-walks large subtrees (e.g. AppData\Local\Temp) on every event → sustained high CPU on Windows

2 participants