diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2023-05-08 22:03:24 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-05-11 11:07:43 +0200 |
commit | 55bfc12be28d45fc8eb1ce475e577d6341887e00 (patch) | |
tree | 98409d08eb266880ee54869059a2775d6f92c7d1 /worker/maildir | |
parent | 115f7f20946e9ac3014e5814f336cb2173f06ec0 (diff) | |
download | aerc-55bfc12be28d45fc8eb1ce475e577d6341887e00.tar.gz |
maildir: fix FSWatcher handling of events
Commit ef4504e6baf5 ("maildir: fix handling of FSEvents") ambitiously
tried to fix handling of file system events by handling different events
in "proper" ways. Distributions and OSes report these FSEvents
differently which creates a large amount of edge cases on what the right
handling of each individual event should be.
Revert part of ef4504e6baf5 which attempts to issue different messages
based on the event. Add a debounce to file system events and always
trigger a Refetch of the message list. This still fixes one of the
"fixes" the referenced patch attempted at, where the UI was only told to
refetch if the message count increased (but if messages disappeared
externally, the maildir never updated).
Fixes: ef4504e6baf5 ("maildir: fix handling of FSEvents")
Reported-by: Kirill Chibisov <contact@kchibisov.com>
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Kirill Chibisov <contact@kchibisov.com>
Diffstat (limited to 'worker/maildir')
-rw-r--r-- | worker/maildir/worker.go | 62 |
1 files changed, 22 insertions, 40 deletions
diff --git a/worker/maildir/worker.go b/worker/maildir/worker.go index ded0faac..ba72432c 100644 --- a/worker/maildir/worker.go +++ b/worker/maildir/worker.go @@ -14,6 +14,7 @@ import ( "sort" "strings" "sync" + "time" "github.com/emersion/go-maildir" @@ -41,6 +42,8 @@ type Worker struct { selectedInfo *models.DirectoryInfo worker *types.Worker watcher types.FSWatcher + watcherDebounce *time.Timer + fsEvents chan struct{} currentSortCriteria []*types.SortCriterion maildirpp bool // whether to use Maildir++ directory layout capabilities *models.Capabilities @@ -57,8 +60,9 @@ func NewWorker(worker *types.Worker) (types.Backend, error) { Sort: true, Thread: true, }, - worker: worker, - watcher: watch, + worker: worker, + watcher: watch, + fsEvents: make(chan struct{}), }, nil } @@ -85,8 +89,17 @@ func (w *Worker) Run() { select { case action := <-w.worker.Actions: w.handleAction(action) - case ev := <-w.watcher.Events(): - w.handleFSEvent(ev) + case <-w.watcher.Events(): + if w.watcherDebounce != nil { + w.watcherDebounce.Stop() + } + // Debounce FS changes + w.watcherDebounce = time.AfterFunc(50*time.Millisecond, func() { + defer log.PanicHandler() + w.fsEvents <- struct{}{} + }) + case <-w.fsEvents: + w.handleFSEvent() } } } @@ -121,7 +134,7 @@ func (w *Worker) handleAction(action types.WorkerMessage) { } } -func (w *Worker) handleFSEvent(ev *types.FSEvent) { +func (w *Worker) handleFSEvent() { // if there's not a selected directory to rescan, ignore if w.selected == nil { return @@ -133,41 +146,10 @@ func (w *Worker) handleFSEvent(ev *types.FSEvent) { } w.selectedInfo = w.getDirectoryInfo(w.selectedName) - dirInfoMsg := &types.DirectoryInfo{ - Info: w.selectedInfo, - } - - base := filepath.Base(ev.Path) - parts := strings.SplitN(base, ":", 2) - if len(parts) != 2 { - log.Errorf("Couldn't parse key from file: %s", ev.Path) - return - } - msg := w.c.MessageFromKey(*w.selected, parts[0]) - - switch ev.Operation { - case types.FSCreate: - // TODO for FSCreate we should send a new message type that - // creates the message in the UI, does a binary search based on - // current sort criteria and inserts message at proper index - // For now, we just refetch the list. - dirInfoMsg.Refetch = true - case types.FSRename: - msgInfo, err := msg.MessageInfo() - if err != nil { - log.Errorf(err.Error()) - return - } - w.worker.PostMessage(&types.MessageInfo{ - Info: msgInfo, - }, nil) - case types.FSRemove: - w.worker.PostMessage(&types.MessagesDeleted{ - Uids: []uint32{msg.uid}, - }, nil) - } - - w.worker.PostMessage(dirInfoMsg, nil) + w.worker.PostMessage(&types.DirectoryInfo{ + Info: w.selectedInfo, + Refetch: true, + }, nil) } func (w *Worker) done(msg types.WorkerMessage) { |