diff options
-rw-r--r-- | worker/notmuch/eventhandlers.go | 6 | ||||
-rw-r--r-- | worker/notmuch/lib/database.go | 5 | ||||
-rw-r--r-- | worker/notmuch/worker.go | 39 |
3 files changed, 37 insertions, 13 deletions
diff --git a/worker/notmuch/eventhandlers.go b/worker/notmuch/eventhandlers.go index 7cd9c6fc..2b03d68b 100644 --- a/worker/notmuch/eventhandlers.go +++ b/worker/notmuch/eventhandlers.go @@ -12,15 +12,15 @@ import ( ) func (w *worker) handleNotmuchEvent(et eventType) error { - switch ev := et.(type) { + switch et.(type) { case *updateDirCounts: - return w.handleUpdateDirCounts(ev) + return w.handleUpdateDirCounts() default: return errUnsupported } } -func (w *worker) handleUpdateDirCounts(ev eventType) error { +func (w *worker) handleUpdateDirCounts() error { if w.store != nil { folders, err := w.store.FolderMap() if err != nil { diff --git a/worker/notmuch/lib/database.go b/worker/notmuch/lib/database.go index 79bf5be3..a965bb62 100644 --- a/worker/notmuch/lib/database.go +++ b/worker/notmuch/lib/database.go @@ -62,6 +62,11 @@ func (db *DB) connect(writable bool) error { return nil } +// Returns the DB path +func (db *DB) Path() string { + return db.db.Path() +} + // withConnection calls callback on the DB object, cleaning up upon return. // the error returned is from the connection attempt, if not successful, // or from the callback otherwise. diff --git a/worker/notmuch/worker.go b/worker/notmuch/worker.go index 3a5dc141..49e598bf 100644 --- a/worker/notmuch/worker.go +++ b/worker/notmuch/worker.go @@ -13,6 +13,7 @@ import ( "net/url" "os" "os/exec" + "path" "path/filepath" "strconv" "strings" @@ -34,8 +35,6 @@ func init() { var errUnsupported = fmt.Errorf("unsupported command") -const backgroundRefreshDelay = 1 * time.Minute - type worker struct { w *types.Worker nmEvents chan eventType @@ -47,14 +46,21 @@ type worker struct { db *notmuch.DB setupErr error currentSortCriteria []*types.SortCriterion + watcher types.FSWatcher + watcherDebounce *time.Timer } // NewWorker creates a new notmuch worker with the provided worker. func NewWorker(w *types.Worker) (types.Backend, error) { events := make(chan eventType, 20) + watcher, err := handlers.NewWatcher() + if err != nil { + return nil, fmt.Errorf("(%s) could not create file system watcher: %w", w.Name, err) + } return &worker{ w: w, nmEvents: events, + watcher: watcher, }, nil } @@ -81,6 +87,15 @@ func (w *worker) Run() { if err != nil { log.Errorf("notmuch event failure: %v", err) } + 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.nmEvents <- &updateDirCounts{} + }) } } } @@ -203,14 +218,13 @@ func (w *worker) handleConnect(msg *types.Connect) error { } w.done(msg) w.emitLabelList() - go func() { - defer log.PanicHandler() - - for { - w.nmEvents <- &updateDirCounts{} - time.Sleep(backgroundRefreshDelay) - } - }() + // Watch all the files in the xapian folder for changes. We'll debounce + // changes, so catching multiple is ok + dbPath := path.Join(w.db.Path(), ".notmuch", "xapian") + err = w.watcher.Configure(dbPath) + if err != nil { + return err + } return nil } @@ -241,6 +255,11 @@ func (w *worker) handleListDirectories(msg *types.ListDirectories) error { }, }, nil) } + // Update dir counts when listing directories + err := w.handleUpdateDirCounts() + if err != nil { + return err + } w.done(msg) return nil } |