-
Notifications
You must be signed in to change notification settings - Fork 328
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
Various fixes for updating dircounts with watch
enabled
#1881
Conversation
joelim-work
commented
Jan 4, 2025
•
edited
Loading
edited
- Fixes fsnotify 1.8.0 crashes lf on symbolic links #1825
- Fixes File size incorrect after copy #1874
I noticed that with this branch the entire watch feature sometimes stops working. It seems quite random, as if there was a race condition but most often it can be observed during move and delete operations. When I delete a file, nothing seems to happen and I need to manually reload to see the file disappear or be moved. |
I haven't noticed any issues with moving/deleting files so far myself. Moving/deleting files should cause the directory to be reloaded - you can try following the code from |
I tried finding the issue by tracing the path, however the bug appears to be very unreliable. |
If the issue isn't strictly related to move/update, then it sounds more likely that the directory didn't get registered into the watcher. Have you tried adding a Other possibilities is that adding a path can technically fail, see https://pkg.go.dev/github.com/fsnotify/fsnotify#Watcher.Add |
I logged all the path added by the watcher now and found a few more things:
For testing I do have two versions of lf running: I test for the issue by running both versions next to each other on the same path and adding a file in one of the directories displayed by both versions. Version A) is randomly affected by the bug, resulting int he entire watch feature not working I did test Version B) but with fsnotify bumped to v1.8.0 to see if that could be the issue but I did not observe any change. |
I rebased the branch and force-pushed it to clean up commit history a bit, but the code is still the same. However I still have no idea what the issue is, because I can't reproduce it on my end. Given that the paths are being watched, I'm surprised it doesn't work for you, since the code here only changes how directories are watched, and not how updates are applied in response to watch events. I guess there are other possibilities though, for example:
To get to the bottom of this, you'll probably have to log events and trace the code from there, something like below: diff --git a/watch.go b/watch.go
index d4f70d3..d4e38a0 100644
--- a/watch.go
+++ b/watch.go
@@ -81,6 +81,7 @@ func (watch *watch) loop() {
for {
select {
case ev := <-watch.events:
+ log.Printf("fsnotify event: %v", ev)
if ev.Has(fsnotify.Create) {
dir := filepath.Dir(ev.Name)
watch.addLoad(dir) |
Thanks, I may have found the issue with that event logging: The system I tested this on uses systemd.homed which has the home directory at /home/myuser.homedir and mount the real home to /home/myuser at login. That means the same files exist at both locations. When I logged the events like suggested above and added a file in my home directory, the file was logged as fsnotify event in /home/myuser.homedir twice but never in /home/myuser. |
OK I see the problem now. So I think the reason why the original code happens to 'work' is because the order in which the paths are registered is somewhat consistent, whereas after 539e333 the path is registered when the directory finishes loading (asynchronously from a separate goroutine). But even then, the event will still only be reported for a single path - it's just that in your case it is the path that you were expecting. If you really want, I can leave out 539e333, but it's sort of just a band-aid fix which hides the real issue in fsnotify. |
This construct of mounted home directories is not too uncommon, even outside of systemd. Consequently I would argue to keep lf compatible with this while we report the issue to fsnotify to fix. Once they have released a new version to address this we could merge the changes again. |
Right I'll will revert 539e333 but keep the diff here just in case I need it again: Click to expanddiff --git a/app.go b/app.go
index 01ecce3..edd891b 100644
--- a/app.go
+++ b/app.go
@@ -427,7 +427,7 @@ func (app *app) loop() {
}
}
- app.addWatchPaths()
+ app.watchDir(d)
app.ui.draw(app.nav)
case r := <-app.nav.regChan:
@@ -633,21 +633,17 @@ func (app *app) runShell(s string, args []string, prefix string) {
}
}
-func (app *app) addWatchPaths() {
- if !gOpts.watch || len(app.nav.dirs) == 0 {
+func (app *app) watchDir(dir *dir) {
+ if !gOpts.watch {
return
}
- paths := make(map[string]bool)
- for _, dir := range app.nav.dirs {
- paths[dir.path] = true
- }
+ app.watch.add(dir.path)
- for _, file := range app.nav.currDir().allFiles {
+ // ensure dircounts are updated for child directories
+ for _, file := range dir.allFiles {
if file.IsDir() {
- paths[file.path] = true
+ app.watch.add(file.path)
}
}
-
- app.watch.add(paths)
}
diff --git a/eval.go b/eval.go
index ecd5a05..e222e44 100644
--- a/eval.go
+++ b/eval.go
@@ -195,7 +195,9 @@ func (e *setExpr) eval(app *app, args []string) {
if err == nil {
if gOpts.watch {
app.watch.start()
- app.addWatchPaths()
+ for _, dir := range app.nav.dirCache {
+ app.watchDir(dir)
+ }
} else {
app.watch.stop()
}
@@ -582,7 +584,6 @@ func preChdir(app *app) {
func onChdir(app *app) {
app.nav.addJumpList()
- app.addWatchPaths()
if cmd, ok := gOpts.cmds["on-cd"]; ok {
cmd.eval(app, nil)
}
diff --git a/watch.go b/watch.go
index 824bb90..f93da25 100644
--- a/watch.go
+++ b/watch.go
@@ -64,14 +64,12 @@ func (watch *watch) stop() {
watch.events = nil
}
-func (watch *watch) add(paths map[string]bool) {
+func (watch *watch) add(path string) {
if watch.watcher == nil {
return
}
- for path := range paths {
- watch.watcher.Add(path)
- }
+ watch.watcher.Add(path)
}
func (watch *watch) loop() { So to summarize, the changes added will be:
That's the best I can do for now, anything else is pretty much going to run into the issue with mounted directories. |
This now seems like a stable solution ready to be merged. |
watch
enabled
8b42eba
to
a1469fa
Compare