Repository navigation
watch the project folder by folder on linux, so a clangd restart no longer freezes the backend - #161
Merged
Merged
Conversation
…ld or clangd's index
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Linux the backend froze for up to half a minute. Both freezes in irrl's log follow a clangd restart:
gitStatus34.9 s,readFile29.3 s,ping14.5 s).#159 fixed a real stall when a program floods the Output panel, but it was not this one.
Why
The backend watches the project folder so the Commit view and the explorer follow changes on disk. It used
fs.watch(root, { recursive: true }). On Linux, Node implements that in JavaScript (internal/fs/recursive_watch, unchanged in Electron 44's Node 24.21), synchronously on the event loop. It:statSyncon every file;readdirSyncon each change inside it;clangd restarted with
--background-indexrewrites its index in_build/<type>/.cache/clangd/index, inside the watched tree. Real Glist projects have about 1,940 index files there (BouncingBalls 1,909, NeonDodger 1,942), and each is written as a temporary file renamed over the old one. The_buildand.cachefilter only ran on the events afterwards, so it saved none of this work.What changed
src/tree-watch.ts: on Linux, one watch per folder, never per file. Ignored folders are never entered. New and deleted folders are found with asyncreaddir/lstat. Symbolic links are not followed, so a link to a folder above can't loop.ENOSPC), or a folder that vanished, is skipped. The focus and save refreshes still work.src/git-service.tsuses it. What is left out (ignoredInProject):_build,node_modulesand.cacheat the project's top;.git/objectsand.git/logs.For a repository folder kept outside the project, its
objectsandlogsare left out (ignoredInGitDir). Changes still arrive as one debouncedgit:changed, as before.Measured
In a Linux container under Electron 44's Node 24.21, a separate process wrote into the project the way clangd and a file manager do:
assets/With an engine-sized build folder (10,000 files) beside the index rewrite, today's watcher held the backend for 28.6 s, about what the log shows. It also slowed the writing process itself, from 0.1 s to 28.7 s, so builds and indexing were being slowed too.
I also tried Node's own
ignoreoption forfs.watch. It fixes the index case (5 ms), but copying 2,000 assets still held the backend for 5.5 s, so a game project's asset folders needed the folder-by-folder watch anyway.Tests
tests/tree-watch.test.mjs, on every OS:_build, clangd's index or Git's objects;It runs both ways on macOS, by folder on Linux, and recursive on Windows, where a watched folder can't be deleted.
On Linux, the same test also measures the stall: with real inotify, it rewrites 1,940 index files and copies 2,000 assets from a separate process, and checks that the backend is never held for 500 ms or more and that there are at most 20 kernel watches. It passes in the container under both Electron's Node 24 and Node 22, as CI's Ubuntu runner will run it. Pointed at today's recursive watch, it fails: 1,962 watches, and the backend held for 16.7 s.
tsc,lint,npm testand all 25 e2e flows pass on macOS. The flows pass again with the folder-by-folder watcher forced on, which exercises it through the explorer and Commit view.Not verified
🤖 Generated with Claude Code