mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-21 08:01:30 +00:00
feat: return the message count from the sync SELECT and skip FETCH on empty mailboxes - a 1:* sequence set against zero messages is a server error, so every fresh mailbox failed its first sync pass before any mail arrived
This commit is contained in:
@@ -26,12 +26,16 @@ func (w *WMail) Sync(ctx context.Context) *errx.MailError {
|
||||
}
|
||||
|
||||
// FETCH requires a selected mailbox; the select also arms
|
||||
// CONDSTORE for the ChangedSince filtering.
|
||||
if err := w.SmtpImapData.ImapClient.SelectForSync(box.Name); err != nil {
|
||||
// CONDSTORE for the ChangedSince filtering. An empty mailbox is
|
||||
// skipped: 1:* on zero messages is a server error.
|
||||
count, err := w.SmtpImapData.ImapClient.SelectForSync(box.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.SmtpImapData.ImapClient.FetchChanges(ctx, 0); err != nil {
|
||||
return err
|
||||
if count > 0 {
|
||||
if err := w.SmtpImapData.ImapClient.FetchChanges(ctx, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
w.SmtpImapData.Mailboxes = append(w.SmtpImapData.Mailboxes, &box)
|
||||
@@ -40,11 +44,14 @@ func (w *WMail) Sync(ctx context.Context) *errx.MailError {
|
||||
|
||||
if befBox.HighestModSeq != box.HighestModSeq {
|
||||
w.SmtpImapData.mailbox = box.UIDValidity
|
||||
if err := w.SmtpImapData.ImapClient.SelectForSync(box.Name); err != nil {
|
||||
count, err := w.SmtpImapData.ImapClient.SelectForSync(box.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.SmtpImapData.ImapClient.FetchChanges(ctx, befBox.HighestModSeq); err != nil {
|
||||
return err
|
||||
if count > 0 {
|
||||
if err := w.SmtpImapData.ImapClient.FetchChanges(ctx, befBox.HighestModSeq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,14 +178,17 @@ func (c *Client) Mailbox(mailbox string, uidvali, opts *imap.SelectOptions) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
// SelectForSync opens a mailbox read-only with CONDSTORE enabled. FETCH is
|
||||
// only valid against a selected mailbox, so the sync loop must call this
|
||||
// before FetchChanges; CONDSTORE on the SELECT is what arms ChangedSince.
|
||||
func (c *Client) SelectForSync(mailbox string) *errx.MailError {
|
||||
if _, err := c.client.Select(mailbox, &imap.SelectOptions{ReadOnly: true, CondStore: true}).Wait(); err != nil {
|
||||
return c.handleError(err)
|
||||
// SelectForSync opens a mailbox read-only with CONDSTORE enabled and returns
|
||||
// its message count. FETCH is only valid against a selected mailbox, so the
|
||||
// sync loop must call this before FetchChanges; CONDSTORE on the SELECT is
|
||||
// what arms ChangedSince. The count lets the caller skip the fetch entirely
|
||||
// for an empty mailbox, where a 1:* set is a server error.
|
||||
func (c *Client) SelectForSync(mailbox string) (uint32, *errx.MailError) {
|
||||
data, err := c.client.Select(mailbox, &imap.SelectOptions{ReadOnly: true, CondStore: true}).Wait()
|
||||
if err != nil {
|
||||
return 0, c.handleError(err)
|
||||
}
|
||||
return nil
|
||||
return data.NumMessages, nil
|
||||
}
|
||||
|
||||
func (c *Client) FetchChanges(ctx context.Context, lastModSeq uint64) *errx.MailError {
|
||||
|
||||
Reference in New Issue
Block a user