Repository navigation
Reload cached files for Created watch events - #64909
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Directory deletions can leave symlink caches stale, and ordinary atomic saves unnecessarily traverse every cached alias.
2 open issues
What changed in this PR
Fixes #64195 by refreshing language-server file caches when atomic saves produce Created watch events.
Changes:
- Reloads cached files for created paths, directories, and symlink aliases.
- Compares open-file overlays with disk contents after save and watch events.
- Adds regression coverage for atomic saves and bulk notifications.
| File | Description |
|---|---|
| tsc/internal/project/snapshotfs.go | Expands created events and reloads cached contents. |
| tsc/internal/project/snapshotfs_test.go | Tests created events and symlink cache handling. |
| tsc/internal/project/snapshot.go | Expands events before bulk invalidation. |
| tsc/internal/project/session_test.go | Tests atomic saves and overlay consistency. |
| tsc/internal/project/overlayfs.go | Updates overlay-to-disk comparisons. |
| tsc/internal/project/overlayfs_test.go | Tests save/watch ordering. |
| tsc/internal/project/bulkcache_test.go | Tests created-event batches and directory notifications. |
Review effort: Balanced
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
I had copilot look at this locally and it noticed a few things
I think the fix itself is right: treating a Created event on a cached file as a possible content change fixes the atomic-save case, and the tests cover it well. My main concern is the disk checks added before the large-batch check (see the comments on snapshot.go and the two DirectoryExists calls), and I think they can be removed entirely.
|
|
||
| if events.saved { | ||
| if o != nil { | ||
| if o != nil && (events.watchObserved || events.saved) { |
There was a problem hiding this comment.
Nit: with this change, every didSave reads the file from disk while holding fs.mu. Before, an open file was simply assumed to match the disk after a save. Comparing against the disk is more accurate, so this is probably fine, but I wanted to point out the extra read on every save.
Jake Bailey (jakebailey)
left a comment
There was a problem hiding this comment.
Minor follow-up idea: the post-expansion Created set can still look excessive to configFileRegistryBuilder.DidChangeFiles, which may clear the config cache.

Fixes #64195
Atomic saves replace an existing file by renaming a temporary file over it; file watchers can report that replacement as
Createdrather thanChanged. We previously only invalidated the cache onChangedevents; when a file that already exists in the program received aCreatedevent, its cached contents remained stale, causing diagnostics to reflect outdated info.