diff options
author | Tristan Partin <tristan@partin.io> | 2024-05-11 14:15:04 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-05-28 23:52:37 +0200 |
commit | f9113810cc6cace71ab4dc506f1b106e4ae9f8dd (patch) | |
tree | 79c3a7b307eb1a9fe0cf006826cc00afabd86b6c | |
parent | 36457f82f22dd98125f845c908a342a1bebb3a8f (diff) | |
download | aerc-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.go | 39 | ||||
-rw-r--r-- | worker/jmap/state.go | 29 |
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 +} |