~rjarry/aerc-devel

This thread contains a patchset. You're looking at the original emails, but you may wish to use the patch review UI. Review patch
2 2

[PATCH aerc] imap: drain updates channel when deleting messages

Details
Message ID
<20240225114838.99343-1-koni.marti@gmail.com>
DKIM signature
pass
Download raw message
Patch: +40 -0
Drain the buffered updates channel when deleting messages to prevent a
backend freeze. Unilateral update messages from the IMAP server can fill
up the buffered channel if not handled during a large operation (more
than ~50 messages).

Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3CCZCPBTWI3PIW.T8MWNCBG7FGL%40disroot.org%3E
Changelog-fixed: Prevent a freeze for large-scale deletions with IMAP.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
---
 worker/imap/flags.go | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/worker/imap/flags.go b/worker/imap/flags.go
index 06680818..60137bd3 100644
--- a/worker/imap/flags.go
+++ b/worker/imap/flags.go
@@ -2,13 +2,53 @@ package imap

import (
	"github.com/emersion/go-imap"
	"github.com/emersion/go-imap/client"

	"git.sr.ht/~rjarry/aerc/lib/log"
	"git.sr.ht/~rjarry/aerc/models"
	"git.sr.ht/~rjarry/aerc/worker/types"
)

// drainUpdates will drain the updates channel. For some operations, the imap
// server will send unilateral messages. If they arrive while another operation
// is in progress, the buffered updates channel can fill up and cause a freeze
// of the entire backend. Avoid this by draining the updates channel and only
// process the Message and Expunge updates.
//
// To stop the draining, close the returned struct.
func (imapw *IMAPWorker) drainUpdates() *drainCloser {
	done := make(chan struct{})
	go func() {
		defer log.PanicHandler()
		for {
			select {
			case update := <-imapw.updates:
				switch update.(type) {
				case *client.MessageUpdate,
					*client.ExpungeUpdate:
					imapw.handleImapUpdate(update)
				}
			case <-done:
				return
			}
		}
	}()
	return &drainCloser{done}
}

type drainCloser struct {
	done chan struct{}
}

func (d *drainCloser) Close() error {
	close(d.done)
	return nil
}

func (imapw *IMAPWorker) handleDeleteMessages(msg *types.DeleteMessages) {
	drain := imapw.drainUpdates()
	defer drain.Close()

	item := imap.FormatFlagsOp(imap.AddFlags, true)
	flags := []interface{}{imap.DeletedFlag}
	uids := toSeqSet(msg.Uids)
-- 
2.44.0

[aerc/patches] build success

builds.sr.ht <builds@sr.ht>
Details
Message ID
<CZE4Z13FEB28.1S6VY4PZ6YLCG@fra02>
In-Reply-To
<20240225114838.99343-1-koni.marti@gmail.com> (view parent)
DKIM signature
missing
Download raw message
aerc/patches: SUCCESS in 2m11s

[imap: drain updates channel when deleting messages][0] from [Koni Marti][1]

[0]: https://lists.sr.ht/~rjarry/aerc-devel/patches/49788
[1]: koni.marti@gmail.com

✓ #1157024 SUCCESS aerc/patches/openbsd.yml     https://builds.sr.ht/~rjarry/job/1157024
✓ #1157023 SUCCESS aerc/patches/alpine-edge.yml https://builds.sr.ht/~rjarry/job/1157023

Applied: [PATCH aerc] imap: drain updates channel when deleting messages

Details
Message ID
<170893598693.234921.9345704144847635634@ringo>
In-Reply-To
<20240225114838.99343-1-koni.marti@gmail.com> (view parent)
DKIM signature
pass
Download raw message
Koni Marti <koni.marti@gmail.com> wrote:
> Drain the buffered updates channel when deleting messages to prevent a
> backend freeze. Unilateral update messages from the IMAP server can fill
> up the buffered channel if not handled during a large operation (more
> than ~50 messages).
>
> Link: https://lists.sr.ht/~rjarry/aerc-discuss/%3CCZCPBTWI3PIW.T8MWNCBG7FGL%40disroot.org%3E
> Changelog-fixed: Prevent a freeze for large-scale deletions with IMAP.
> Signed-off-by: Koni Marti <koni.marti@gmail.com>
> ---

Tested-by: Jeremy Baxter <jtbx@disroot.org>
Acked-by: Robin Jarry <robin@jarry.cc>

Applied, thanks.

To git@git.sr.ht:~rjarry/aerc
   83c3a4051b14..d8d5fc8d31f3  master -> master
Reply to thread Export thread (mbox)