aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-02-05 00:07:16 +0100
committerRobin Jarry <robin@jarry.cc>2022-02-06 17:06:20 +0100
commit05ad96a30cb8ea17970c84ea7c72f8f3def5afa5 (patch)
treefdacf5548477bf0f470793d50885f6ea82210191
parent4bd4f4664a36f22efad6f6a2cf8861928098e8c4 (diff)
downloadaerc-05ad96a30cb8ea17970c84ea7c72f8f3def5afa5.tar.gz
aerc-05ad96a30cb8ea17970c84ea7c72f8f3def5afa5.zip
imap: improve reconnect stability
improves the robustness of the imap reconnect feature which was introduced in commit beae17a6da37 ("imap: auto-reconnects on connection error"). If a connection error is emitted, the message list is cleared and a corresponding error message is shown in the ui. Status bar is updated as well. Upon reconnect, the directories and the message list will be re-fetched (same behavior as the connect command). Reconnect can be enabled and disabled with the connect and the disconnect commands. Signed-off-by: Koni Marti <koni.marti@gmail.com>
-rw-r--r--widgets/account.go4
-rw-r--r--worker/imap/worker.go26
2 files changed, 22 insertions, 8 deletions
diff --git a/widgets/account.go b/widgets/account.go
index f9700301..8dbaba3e 100644
--- a/widgets/account.go
+++ b/widgets/account.go
@@ -289,8 +289,10 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
case *types.LabelList:
acct.labels = msg.Labels
case *types.ConnError:
- acct.logger.Printf("Connection error = %v", msg.Error)
+ acct.logger.Printf("connection error: %v", msg.Error)
+ acct.host.SetStatus("Disconnected.")
acct.aerc.PushError(fmt.Sprintf("%v", msg.Error))
+ acct.msglist.SetStore(nil)
acct.worker.PostAction(&types.Reconnect{}, nil)
case *types.Error:
acct.logger.Printf("%v", msg.Error)
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index ba53df23..a1d55b9e 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -85,6 +85,11 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
}
}()
+ checkConn := func() {
+ w.stopConnectionObserver()
+ w.startConnectionObserver()
+ }
+
var reterr error // will be returned at the end, needed to support idle
switch msg := msg.(type) {
@@ -171,9 +176,15 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
}
case *types.Connect:
if w.client != nil && w.client.State() == imap.SelectedState {
+ if !w.autoReconnect {
+ w.autoReconnect = true
+ checkConn()
+ }
reterr = fmt.Errorf("Already connected")
break
}
+
+ w.autoReconnect = true
c, err := w.connect()
if err != nil {
reterr = err
@@ -187,7 +198,6 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.startConnectionObserver()
- w.autoReconnect = true
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.Reconnect:
if !w.autoReconnect {
@@ -196,6 +206,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
}
c, err := w.connect()
if err != nil {
+ checkConn()
reterr = err
break
}
@@ -209,18 +220,17 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.Disconnect:
+ w.autoReconnect = false
+ w.stopConnectionObserver()
if w.client == nil || w.client.State() != imap.SelectedState {
reterr = fmt.Errorf("Not connected")
break
}
- w.stopConnectionObserver()
-
if err := w.client.Logout(); err != nil {
reterr = err
break
}
- w.autoReconnect = false
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories:
w.handleListDirectories(msg)
@@ -306,9 +316,11 @@ func (w *IMAPWorker) startConnectionObserver() {
go func() {
select {
case <-w.client.LoggedOut():
- w.worker.PostMessage(&types.ConnError{
- Error: fmt.Errorf("Logged Out"),
- }, nil)
+ if w.autoReconnect {
+ w.worker.PostMessage(&types.ConnError{
+ Error: fmt.Errorf("imap: logged out"),
+ }, nil)
+ }
case <-w.done:
return
}