aboutsummaryrefslogtreecommitdiffstats
path: root/worker/maildir/worker.go
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2023-05-08 22:03:24 -0500
committerRobin Jarry <robin@jarry.cc>2023-05-11 11:07:43 +0200
commit55bfc12be28d45fc8eb1ce475e577d6341887e00 (patch)
tree98409d08eb266880ee54869059a2775d6f92c7d1 /worker/maildir/worker.go
parent115f7f20946e9ac3014e5814f336cb2173f06ec0 (diff)
downloadaerc-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/worker.go')
-rw-r--r--worker/maildir/worker.go62
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) {