Handle incoming emails gracefully

This commit is contained in:
Drew DeVault 2019-05-13 20:16:55 -04:00
parent bb46b2b7e1
commit 026e8a17ca
5 changed files with 36 additions and 9 deletions

View file

@ -1,6 +1,7 @@
package lib
import (
"fmt"
"io"
"sync"
"time"
@ -140,6 +141,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
switch msg := msg.(type) {
case *types.DirectoryInfo:
store.DirInfo = *msg
fmt.Printf("got dirinfo, %d exists, %d known\n",
store.DirInfo.Exists, len(store.Uids))
if store.DirInfo.Exists != len(store.Uids) {
store.worker.PostAction(&types.FetchDirectoryContents{}, nil)
}
update = true
case *types.DirectoryContents:
newMap := make(map[uint32]*types.MessageInfo)

View file

@ -161,17 +161,17 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
} else {
acct.msglist.SetStore(nil)
}
acct.worker.PostAction(&types.FetchDirectoryContents{},
func(msg types.WorkerMessage) {
store := acct.msgStores[acct.dirlist.selected]
acct.msglist.SetStore(store)
})
}
case *types.DirectoryInfo:
if store, ok := acct.msgStores[msg.Name]; ok {
store.Update(msg)
} else {
acct.msgStores[msg.Name] = lib.NewMessageStore(acct.worker, msg)
store = lib.NewMessageStore(acct.worker, msg)
acct.msgStores[msg.Name] = store
store.OnUpdate(func(_ *lib.MessageStore) {
store.OnUpdate(nil)
acct.msglist.SetStore(store)
})
}
case *types.DirectoryContents:
store := acct.msgStores[acct.dirlist.selected]

View file

@ -109,6 +109,7 @@ func (ml *MessageList) Height() int {
}
func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
ml.logger.Println("message store updated")
if ml.Store() != store {
return
}

View file

@ -17,6 +17,9 @@ func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) {
}, nil)
} else {
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
if imapw.idleStop == nil {
imapw.idleStop = make(chan struct{})
}
}
}

View file

@ -18,7 +18,7 @@ var errUnsupported = fmt.Errorf("unsupported command")
type imapClient struct {
*client.Client
*idle.IdleClient
idle *idle.IdleClient
}
type IMAPWorker struct {
@ -30,6 +30,8 @@ type IMAPWorker struct {
}
client *imapClient
idleStop chan struct{}
idleDone chan error
selected imap.MailboxStatus
updates chan client.Update
worker *types.Worker
@ -39,6 +41,7 @@ type IMAPWorker struct {
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
return &IMAPWorker{
idleDone: make(chan error),
updates: make(chan client.Update, 50),
worker: worker,
}
@ -80,6 +83,13 @@ func (w *IMAPWorker) verifyPeerCert(msg types.WorkerMessage) func(
}
func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
if w.idleStop != nil {
close(w.idleStop)
if err := <-w.idleDone; err != nil {
w.worker.PostMessage(&types.Error{Error: err}, nil)
}
}
switch msg := msg.(type) {
case *types.Unsupported:
// No-op
@ -167,6 +177,13 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
default:
return errUnsupported
}
if w.idleStop != nil {
w.idleStop = make(chan struct{})
go func() {
w.idleDone <- w.client.idle.IdleWithFallback(w.idleStop, 0)
}()
}
return nil
}