fix(tui): bound @-completion file-index walk with a wall-clock budget (#4365)#4367
fix(tui): bound @-completion file-index walk with a wall-clock budget (#4365)#4367LeoLin990405 wants to merge 1 commit into
Conversation
…Hmbown#4365) The @-mention fuzzy-completion index is built synchronously on the input thread whenever the walk root changes, e.g. @-mentioning a non-workspace directory. The existing FILE_INDEX_MAX_ENTRIES cap bounds the result size but not the time to reach it: walking a large external tree with no .gitignore can spend seconds before hitting 50k entries, freezing the TUI (pwsh7 in the report). Add a 150ms wall-clock budget checked alongside the entry cap in every walk loop of build_file_index; over budget, return the partial index rather than blocking. Partial completions beat an unresponsive terminal, and the next keystroke re-walks from cache. Extract build_file_index_with_budget so the budget is unit-testable, and add a deterministic test.
|
Thanks @LeoLin990405 for taking the time to contribute. This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered. Please read |
Hmbown
left a comment
There was a problem hiding this comment.
Thank you for taking on #4365. I cannot merge this version yet because the wall-clock check happens inside each for body, after the iterator has already completed next(). A single slow filesystem read can therefore still block the input thread past the budget. local_reference_paths(...) is also materialized before its loop can check elapsed time, and a partial cache miss may repeat the synchronous walk on later input.
Please move completion discovery off the UI/input thread (with serialized scans and stale-result protection), or make the traversal itself genuinely interruptible before a blocking next(). The regression should prove that key handling stays responsive while discovery is stalled, in addition to checking partial results. The current Lint and Windows jobs are also red. I am happy to re-review a focused update, and your contribution will retain credit when the complete fix lands.
Problem
Fixes #4365 —
@-mentioning a large non-workspace directory freezes the TUI (reporter saw an unresponsive terminal on pwsh7). The mention completion pulls the full subtree eagerly.Root cause
The fuzzy-completion index (
Workspace::build_file_indexinworking_set.rs) is rebuilt synchronously on the input thread whenever the walk root changes — which is every keystroke while typing an@-path outside the workspace.FILE_INDEX_MAX_ENTRIES = 50_000caps the result size but not the time to reach it: a large external tree with no.gitignorecan spend seconds walking before it hits 50k entries, and that whole time the UI is blocked.Fix
Add a 150ms wall-clock budget (
COMPLETION_WALK_BUDGET) checked alongside the existing entry cap in every walk loop ofbuild_file_index. Once the budget is exceeded the build returns the partial index instead of continuing — partial completions are far better than an unresponsive terminal, and the next keystroke re-walks (from cache when the root is unchanged). The dot-dir andlocal_reference_pathspasses are skipped once over budget so they can't reintroduce the freeze.build_file_indexis split intobuild_file_index_with_budget(budget)so the behavior is unit-testable; the public path calls it withCOMPLETION_WALK_BUDGET, so nothing else changes for normal-sized workspaces (the budget is a no-op there, same as the entry cap).Testing
build_file_index_respects_time_budget: a generous budget indexes every file; a zero budget stops the walk early (returns fewer entries) — proving the build can't block. Deterministic, no reliance on a real slow filesystem.cargo clippy -p codewhale-tui --all-featuresclean;cargo test -p codewhale-tui --all-features working_setgreen (44 passed).Note: I couldn't reproduce the actual freeze on macOS (the report is pwsh7/Windows on a huge external tree), but the time budget is platform-agnostic hardening of the exact synchronous walk named in the issue. Happy to adjust the 150ms value or the approach (e.g. debounce until the path is committed, per the reporter's suggestion) if you'd prefer.