From 17718981c5d1db0775407d45f83dcd026758ab47 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 28 Nov 2022 21:15:38 -0600 Subject: imap: use list-status for check-mail Use list-status to perform check-mail commands, if it is available. This provides a significant performance benefit by only requiring one IMAP command vs one command for each mailbox. Signed-off-by: Tim Culverhouse Acked-by: Robin Jarry --- worker/imap/checkmail.go | 67 +++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 24 deletions(-) (limited to 'worker') diff --git a/worker/imap/checkmail.go b/worker/imap/checkmail.go index 34cf63d1..8f9e1b2b 100644 --- a/worker/imap/checkmail.go +++ b/worker/imap/checkmail.go @@ -13,36 +13,55 @@ func (w *IMAPWorker) handleCheckMailMessage(msg *types.CheckMail) { imap.StatusRecent, imap.StatusUnseen, } - var remaining []string - for _, dir := range msg.Directories { - if len(w.worker.Actions) > 0 { - remaining = append(remaining, dir) - continue - } - - log.Tracef("Getting status of directory %s", dir) - status, err := w.client.Status(dir, items) + var ( + statuses []*imap.MailboxStatus + err error + remaining []string + ) + switch { + case w.liststatus: + log.Tracef("Checking mail with LIST-STATUS") + statuses, err = w.client.liststatus.ListStatus("", "*", items, nil) if err != nil { w.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) - } else { - w.worker.PostMessage(&types.DirectoryInfo{ - Info: &models.DirectoryInfo{ - Flags: status.Flags, - Name: status.Name, - ReadOnly: status.ReadOnly, - AccurateCounts: true, - - Exists: int(status.Messages), - Recent: int(status.Recent), - Unseen: int(status.Unseen), - Caps: w.caps, - }, - SkipSort: true, - }, nil) + return } + default: + for _, dir := range msg.Directories { + if len(w.worker.Actions) > 0 { + remaining = append(remaining, dir) + continue + } + log.Tracef("Getting status of directory %s", dir) + status, err := w.client.Status(dir, items) + if err != nil { + w.worker.PostMessage(&types.Error{ + Message: types.RespondTo(msg), + Error: err, + }, nil) + continue + } + statuses = append(statuses, status) + } + } + for _, status := range statuses { + w.worker.PostMessage(&types.DirectoryInfo{ + Info: &models.DirectoryInfo{ + Flags: status.Flags, + Name: status.Name, + ReadOnly: status.ReadOnly, + AccurateCounts: true, + + Exists: int(status.Messages), + Recent: int(status.Recent), + Unseen: int(status.Unseen), + Caps: w.caps, + }, + SkipSort: true, + }, nil) } if len(remaining) > 0 { w.worker.PostMessage(&types.CheckMailDirectories{ -- cgit