Repository navigation
fix(watcher): update notify to rc.8 to fix macOS root-switch hangs - #939
Conversation
notify's FsEventWatcher restarts its stream on every watch() and can lose a CFRunLoopStop issued right after a start, leaving the caller in pthread_join forever. create_debouncer hit that twice per watcher (base, .git, .git/logs). Register all paths with one update_paths call on recursive backends. The stuck pool worker then deadlocked every later scan through the blocking BACKGROUND_THREAD_POOL.broadcast in hint_allocator_collect and release_thread_buffers. Use spawn_broadcast so cleanup never waits on a busy worker. Closes #938
There was a problem hiding this comment.
Your trial has ended. Reactivate Greptile to resume code reviews.
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
| // The .git directory is excluded from the file list but we still need | ||
| // to observe changes that affect git status (staging, unstaging, | ||
| // committing, branch switches, merges, etc) | ||
| watch_git_status_paths(&mut debouncer, git_workdir.as_ref()); |
There was a problem hiding this comment.
@gustav-fff wtf wy did yo do that? this was the code I wrote to avoid watching git internals this exceeds fs events and inotify limits
There was a problem hiding this comment.
[triage-bot] DIRECTED: Nothing new is watched. Watched set is the same as on main: base + .git NonRecursive + .git/logs NonRecursive. No .git recursion was added.
The diff shows watch_git_status_paths as deleted, but it was only split:
git_status_paths(background_watcher.rs:1042) is the same function with the sameis_dirchecks and the same two paths. It just returns them instead of callingwatch().- Linux/inotify (
:308): samewatch(path, NonRecursive)loop, same position after the per-dir watches. Same behavior. - macOS/Windows (
:246): the same two paths go into oneupdate_pathswith the base, asPathOp::watch_non_recursive. In notify9.0.0-rc.4,FsEventWatcher::update_paths_innerrunsappend_path(path, config.recursive_mode())for each op, between onestop()and onerun(). Before, it ran 3watch()calls, so 3 stop/run cycles, and each cycle can hit the [Suggestion]: pause git status work while the picker UI is closed #942 hang. The final stream has the same 3 paths with the sameis_recursiveflags. Windows uses the defaultupdate_paths, which callswatch()in a loop, so nothing changes there.
One real difference: if .git fails in the batch, .git/logs is skipped (remaining is dropped). Before, each path was tried separately. Only warn! either way.
If you want the old watch_git_status_paths shape kept for the inotify branch and only the FSEvents call batched, say so and I'll push it.
Honk-Honk 🪿
There was a problem hiding this comment.
@gustav-fff yes please get rid of this uselles vec allocation
There was a problem hiding this comment.
[triage-bot] DIRECTED: Pushed 0b349fd. Both Vecs are gone.
git_status_paths(background_watcher.rs:1044) returnsimpl Iterator<Item = PathBuf>, built fromOption<.git>.chain(Option<.git/logs>). Sameis_dirchecks, no heap.- FSEvents (
:240):iter::once(base).chain(git_status_paths(..).map(PathOp::watch_non_recursive))goes straight intoupdate_paths. NoopsVec on our side. - inotify (
:306):watch_git_status_paths(&mut debouncer, git_workdir.as_ref())is back, same shape as before.
The one Vec left is in fff-notify-debouncer-full::update_paths (lib.rs:674), because notify's Watcher::update_paths takes Vec<PathOp>. That is the API. It runs once per watcher.
make lint-rust clean, cargo fmt --check clean, make test-rust 0 failed.
Honk-Honk 🪿
git_status_paths now returns an Option-chain iterator, the FSEvents batch chains it straight into update_paths, and the inotify branch goes back to watch_git_status_paths.
Update
notifyto9.0.0-rc.8to fix the macOS watcher hang when Neovim switches search roots in quick succession. The release also skips redundant metadata reads when FFF registers directory watches on Linux.Closes #938.
macOS watcher fix · Linux watch registration change
Summary by CodeRabbit