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