-
Notifications
You must be signed in to change notification settings - Fork 714
Simplify and consolidate LSP watcher registrations #1733
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
// !!! what about declaration files in node_modules? wouldn't it be better to | ||
// check project inclusion if the project is already loaded? | ||
if !config.MatchesFileName(fileName) { | ||
if _, ok := config.FileNamesByPath()[path]; !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a drive-by fix, but MatchesFileName
is a more expensive function that speculates about files that may not exist; the usage here was for a file that already exists and is either properly included by the config or not.
assert.Check(t, lsAfter.GetProgram() != programBefore) | ||
}) | ||
|
||
t.Run("change program file not in tsconfig root files", func(t *testing.T) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case exercises logic that was missing from the pre-snapshot LSP port.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removals in this file represent two strategy changes:
- Since we rely on the LSP client to handle the watchers at the system level, remove our logic for avoiding installing watchers too close to the file system root. VS Code installs a watcher at the workspace level no matter that directory’s location, so we have nothing to gain by not using it. Any decision to refuse installing a watcher at a given location belongs to the client; they can simply return an error when we request to watch that location.
- Prefer watching the workspace directory over anything else. If a file is in the workspace, don't register any additional watcher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
} | ||
|
||
// Porting reference: ProjectService.isMatchedByConfig | ||
func (p *ParsedCommandLine) MatchesFileName(fileName string) bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MatchesFileName was no longer being used except for the incorrect usage I pointed out above. When I initially implemented it for file watching, it was a bad performance bottleneck. PossiblyMatchesFileName is less precise but faster. It may be worth revisiting this if we invest into perf improvements of our include/exclude globbing (#1483)
eb8d310
to
8755d8f
Compare
} | ||
|
||
cwd := s.cwd | ||
if s.initializeParams.Capabilities != nil && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Boy do I want to add protobuf-style safe accessors for capabilities
https://gist.github.com/jakebailey/84d5310acdb3397056009e0bbf998070 The big list of paths is me logging all of the files from |
@jakebailey could you try the latest? I walked back some of the deletions while keeping it still much simpler than before. |
Seems better:
Those are all definitely safe paths to watch. |
Though, the workspace ones seem potentially redundant? (Depending on how the editor does things) |
It's not reflected in the logs here, but they appear duplicated because the failed lookups one is a create-only watcher, while the root files for the tsconfig one is a create/change/delete watcher. In theory, one of those could be independently removed if you start opening and closing other projects. We could make a special rule that says “any watcher on the workspace directory is always create/change/delete” but I’m not sure how worthwhile that is. |
This is a weird one; I opened DT tools to
But, that path doesn't exist and isn't mentioned anywhere else in the logs. This is a failed lookup so maybe there's a bad import somewhere that's not resolving, but I can't seem to find it. |
Just realized, |
It looks like the same bug exists in Strada. I prevented the bogus path lookup for now but I’m not sure if a different strategy should be implemented to find the proper peer dep lookup location, or if it doesn’t matter for monorepo packages like this. (@sheetalkamat you might want to look at the last commit) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't find any weird issues when I try this out and read the logs. Worth a shot!
I'll note that in the TS repo, if I delete |
Yeah, that’s microsoft/vscode#109754, and will be handled in a follow-up PR to remove the extensions from our glob patterns. |
I merged main because license/cla was MIA, but I have not super high hopes that a new commit is going to unstick it... |
A close reopen usually fixes it for me. |
Pull request was closed
Pull request was closed
In a large internal monorepo, this cut the number of individual globs we ask the LSP client to watch from 7667 (duplicated and narrower) globs to 7 (deduped and broader) globs, and cut the time it took to compute and register those globs by 80%. This is the basis for two follow-up fixes/improvements:
I want to get reviews on this first, as those fixes will build on this simplification.