Repository navigation
Avoid a full workspace search per Python file event - #1999
om singhal (Om-singhaI) wants to merge 1 commit into
Conversation
The workspaceHasPython watcher called findFiles for every created or deleted marker file, and each call starts its own ripgrep process, so a branch switch that touches a thousand Python files started a thousand workspace searches at once. A created marker file or an opened Python document now sets the context to true without searching. Deletes and workspace folder changes share one rescan, debounced by 500 ms. Only one search runs at a time, a rescan requested meanwhile runs once after it, and a search is cancelled when its result is stale or the extension is disposed. The context is only set when its value changes.
Jean-François Gagné (JeanFrancoisGagne)
left a comment
There was a problem hiding this comment.
Checked this branch on Windows 11 against the case in my #1989 comment: the home folder open as the workspace. Your test file passes (35 of 35) and fails on main (18 failures, for example 1,001 scans for 1,000 creates). I also ran a harness with your stubs, a 40 s fake scan and 5 minutes of temp-file events. A delete every 250 ms went from 1,201 findFiles calls, 161 at once, to 1 call. Create then delete every second went from 601 calls, 81 at once, to 301 calls, one at a time. That removes the cause of our commit-limit crash.
One gap: every delete while the key is true still schedules a rescan, so pytest-style churn starts a new rg each cycle. Keeping the Uri that findFiles returned (maxResults 1 gives exactly one) and rescanning only when a delete hits that Uri would make those deletes free.
|
One case this doesn't cover yet: a single scan that never finishes. Linux, VS Code 1.145.2, Python Environments 1.42.0. The workspace has no marker files at all (a Rust/shell repo), but it does hold a Wine prefix, and Wine's
With this PR there would be one such
Workaround for anyone affected: |
Summary
Since 1.42.0 the
workspaceHasPythonwatcher callsfindFilesfor every created or deleted marker file. Each call starts its ownrg --filesover the workspace, so a branch switch that touches a thousand Python files starts a thousand searches at once, which is the freeze reported in #1989.The change stays in
workspacePythonContext.tsand follows the approach suggested on the issue:truewithout a searchcreateSimpleDebounce(500 ms); deletes are skipped while the context is alreadyfalsefindFilesgets a cancellation token, cancelled when the result is stale or on disposesetContextis only called when the value changesThe activation scan and the excludes are unchanged.
Fixes #1989
Testing
A small harness fired watcher events at
registerWorkspacePythonContextand countedfindFilescalls (total / peak concurrent):The final context value was the same before and after in every case.
npm run compile-tests,npm run lint, and a prettier check on the changed filesnpm run unittest: 3521 passing, 12 pending