diff options
-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 +} |