aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Partin <tristan@partin.io>2024-05-11 14:15:04 -0500
committerRobin Jarry <robin@jarry.cc>2024-05-28 23:52:37 +0200
commitf9113810cc6cace71ab4dc506f1b106e4ae9f8dd (patch)
tree79c3a7b307eb1a9fe0cf006826cc00afabd86b6c
parent36457f82f22dd98125f845c908a342a1bebb3a8f (diff)
downloadaerc-f9113810cc6cace71ab4dc506f1b106e4ae9f8dd.tar.gz
jmap: invalidate cache if mailbox state is not consistent
We weren't checking if the cached state was the same as the remote state before reading it. This led to aerc not knowing about new mailboxes on the remote. Signed-off-by: Tristan Partin <tristan@partin.io> Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/jmap/directories.go39
-rw-r--r--worker/jmap/state.go29
2 files changed, 57 insertions, 11 deletions
diff --git a/worker/jmap/directories.go b/worker/jmap/directories.go
index bc47e691..eac63398 100644
--- a/worker/jmap/directories.go
+++ b/worker/jmap/directories.go
@@ -21,21 +21,38 @@ func (w *JMAPWorker) handleListDirectories(msg *types.ListDirectories) error {
mboxes = make(map[jmap.ID]*mailbox.Mailbox)
- mboxIds, err := w.cache.GetMailboxList()
- if err == nil {
- for _, id := range mboxIds {
- mbox, err := w.cache.GetMailbox(id)
- if err != nil {
- w.w.Warnf("GetMailbox: %s", err)
- missing = append(missing, id)
- continue
+ currentMailboxState, err := w.getMailboxState()
+ if err != nil {
+ return err
+ }
+
+ // If we can't get the cached mailbox state, at worst, we will just
+ // query information we might already know
+ cachedMailboxState, err := w.cache.GetMailboxState()
+ if err != nil {
+ w.w.Warnf("PutMailboxState: %s", err)
+ }
+
+ consistentMailboxState := currentMailboxState == cachedMailboxState
+
+ // If we have a consistent state, check the cache
+ if consistentMailboxState {
+ mboxIds, err := w.cache.GetMailboxList()
+ if err == nil {
+ for _, id := range mboxIds {
+ mbox, err := w.cache.GetMailbox(id)
+ if err != nil {
+ w.w.Warnf("GetMailbox: %s", err)
+ missing = append(missing, id)
+ continue
+ }
+ mboxes[id] = mbox
+ ids = append(ids, id)
}
- mboxes[id] = mbox
- ids = append(ids, id)
}
}
- if err != nil || len(missing) > 0 {
+ if !consistentMailboxState || len(missing) > 0 {
var req jmap.Request
req.Invoke(&mailbox.Get{Account: w.accountId})
diff --git a/worker/jmap/state.go b/worker/jmap/state.go
new file mode 100644
index 00000000..3dbab3fb
--- /dev/null
+++ b/worker/jmap/state.go
@@ -0,0 +1,29 @@
+package jmap
+
+import (
+ "git.sr.ht/~rockorager/go-jmap"
+ "git.sr.ht/~rockorager/go-jmap/mail/mailbox"
+)
+
+func (w *JMAPWorker) getMailboxState() (string, error) {
+ var req jmap.Request
+
+ req.Invoke(&mailbox.Get{Account: w.accountId, IDs: make([]jmap.ID, 0)})
+ resp, err := w.Do(&req)
+ if err != nil {
+ return "", err
+ }
+
+ for _, inv := range resp.Responses {
+ switch r := inv.Args.(type) {
+ case *mailbox.GetResponse:
+ return r.State, nil
+ case *jmap.MethodError:
+ return "", wrapMethodError(r)
+
+ }
+ }
+
+ // This should be an impossibility
+ return "", nil
+}