diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-04-30 01:08:55 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-05-04 14:07:15 +0200 |
commit | 397a6f267f41c501f28d3adb9d641a9283af474f (patch) | |
tree | 9e30042b2415ed12a22f6be1eb63a00406630957 /worker/imap/worker.go | |
parent | 4d75137b20664cbdf90159c78d1fbf78779f3416 (diff) | |
download | aerc-397a6f267f41c501f28d3adb9d641a9283af474f.zip |
imap: manage idle mode with an idler
Untangle the idle functionality from the message handling routine. Wait
for the idle mode to properly exit every time to ensure a consistent
imap state. Timeout when hanging in idle mode and inform the ui.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/imap/worker.go')
-rw-r--r-- | worker/imap/worker.go | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/worker/imap/worker.go b/worker/imap/worker.go index ad08333..d0f8482 100644 --- a/worker/imap/worker.go +++ b/worker/imap/worker.go @@ -14,7 +14,6 @@ import ( "github.com/pkg/errors" "git.sr.ht/~rjarry/aerc/lib" - "git.sr.ht/~rjarry/aerc/logging" "git.sr.ht/~rjarry/aerc/models" "git.sr.ht/~rjarry/aerc/worker/handlers" "git.sr.ht/~rjarry/aerc/worker/types" @@ -56,44 +55,43 @@ type IMAPWorker struct { config imapConfig client *imapClient - idleStop chan struct{} - idleDone chan error selected *imap.MailboxStatus updates chan client.Update worker *types.Worker // Map of sequence numbers to UIDs, index 0 is seq number 1 - seqMap []uint32 + seqMap []uint32 + done chan struct{} autoReconnect bool retries int + + idler *idler } func NewIMAPWorker(worker *types.Worker) (types.Backend, error) { return &IMAPWorker{ - idleDone: make(chan error), updates: make(chan client.Update, 50), worker: worker, selected: &imap.MailboxStatus{}, + idler: newIdler(imapConfig{}, worker), }, nil } +func (w *IMAPWorker) newClient(c *client.Client) { + c.Updates = w.updates + w.client = &imapClient{c, sortthread.NewThreadClient(c), sortthread.NewSortClient(c)} + w.idler.SetClient(w.client) +} + func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { - if w.client != nil && w.client.State() == imap.SelectedState { - close(w.idleStop) - if err := <-w.idleDone; err != nil { - w.worker.PostMessage(&types.Error{Error: err}, nil) - } - } defer func() { - if w.client != nil && w.client.State() == imap.SelectedState { - w.idleStop = make(chan struct{}) - go func() { - defer logging.PanicHandler() - - w.idleDone <- w.client.Idle(w.idleStop, &client.IdleOptions{LogoutTimeout: 0, PollInterval: 0}) - }() - } + w.idler.Start() }() + if err := w.idler.Stop(); err != nil { + return err + } + + var reterr error // will be returned at the end, needed to support idle checkConn := func(wait time.Duration) { time.Sleep(wait) @@ -101,7 +99,10 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { w.startConnectionObserver() } - var reterr error // will be returned at the end, needed to support idle + // set connection timeout for calls to imap server + if w.client != nil { + w.client.Timeout = w.config.connection_timeout + } switch msg := msg.(type) { case *types.Unsupported: @@ -128,8 +129,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { w.stopConnectionObserver() - c.Updates = w.updates - w.client = &imapClient{c, sortthread.NewThreadClient(c), sortthread.NewSortClient(c)} + w.newClient(c) w.startConnectionObserver() @@ -150,8 +150,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { w.stopConnectionObserver() - c.Updates = w.updates - w.client = &imapClient{c, sortthread.NewThreadClient(c), sortthread.NewSortClient(c)} + w.newClient(c) w.startConnectionObserver() @@ -203,6 +202,11 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { reterr = errUnsupported } + // we don't want idle to timeout, so set timeout to zero + if w.client != nil { + w.client.Timeout = 0 + } + return reterr } @@ -433,6 +437,7 @@ func (w *IMAPWorker) Run() { select { case msg := <-w.worker.Actions: msg = w.worker.ProcessAction(msg) + if err := w.handleMessage(msg); err == errUnsupported { w.worker.PostMessage(&types.Unsupported{ Message: types.RespondTo(msg), @@ -443,6 +448,7 @@ func (w *IMAPWorker) Run() { Error: err, }, nil) } + case update := <-w.updates: w.handleImapUpdate(update) } |