Handle incoming emails gracefully
This commit is contained in:
parent
bb46b2b7e1
commit
026e8a17ca
5 changed files with 36 additions and 9 deletions
|
@ -1,6 +1,7 @@
|
||||||
package lib
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -140,6 +141,11 @@ func (store *MessageStore) Update(msg types.WorkerMessage) {
|
||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case *types.DirectoryInfo:
|
case *types.DirectoryInfo:
|
||||||
store.DirInfo = *msg
|
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
|
update = true
|
||||||
case *types.DirectoryContents:
|
case *types.DirectoryContents:
|
||||||
newMap := make(map[uint32]*types.MessageInfo)
|
newMap := make(map[uint32]*types.MessageInfo)
|
||||||
|
|
|
@ -161,17 +161,17 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
|
||||||
} else {
|
} else {
|
||||||
acct.msglist.SetStore(nil)
|
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:
|
case *types.DirectoryInfo:
|
||||||
if store, ok := acct.msgStores[msg.Name]; ok {
|
if store, ok := acct.msgStores[msg.Name]; ok {
|
||||||
store.Update(msg)
|
store.Update(msg)
|
||||||
} else {
|
} 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:
|
case *types.DirectoryContents:
|
||||||
store := acct.msgStores[acct.dirlist.selected]
|
store := acct.msgStores[acct.dirlist.selected]
|
||||||
|
|
|
@ -109,6 +109,7 @@ func (ml *MessageList) Height() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
|
func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
|
||||||
|
ml.logger.Println("message store updated")
|
||||||
if ml.Store() != store {
|
if ml.Store() != store {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ func (imapw *IMAPWorker) handleOpenDirectory(msg *types.OpenDirectory) {
|
||||||
}, nil)
|
}, nil)
|
||||||
} else {
|
} else {
|
||||||
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
|
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
|
||||||
|
if imapw.idleStop == nil {
|
||||||
|
imapw.idleStop = make(chan struct{})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ var errUnsupported = fmt.Errorf("unsupported command")
|
||||||
|
|
||||||
type imapClient struct {
|
type imapClient struct {
|
||||||
*client.Client
|
*client.Client
|
||||||
*idle.IdleClient
|
idle *idle.IdleClient
|
||||||
}
|
}
|
||||||
|
|
||||||
type IMAPWorker struct {
|
type IMAPWorker struct {
|
||||||
|
@ -30,6 +30,8 @@ type IMAPWorker struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
client *imapClient
|
client *imapClient
|
||||||
|
idleStop chan struct{}
|
||||||
|
idleDone chan error
|
||||||
selected imap.MailboxStatus
|
selected imap.MailboxStatus
|
||||||
updates chan client.Update
|
updates chan client.Update
|
||||||
worker *types.Worker
|
worker *types.Worker
|
||||||
|
@ -39,8 +41,9 @@ type IMAPWorker struct {
|
||||||
|
|
||||||
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
func NewIMAPWorker(worker *types.Worker) *IMAPWorker {
|
||||||
return &IMAPWorker{
|
return &IMAPWorker{
|
||||||
updates: make(chan client.Update, 50),
|
idleDone: make(chan error),
|
||||||
worker: worker,
|
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 {
|
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) {
|
switch msg := msg.(type) {
|
||||||
case *types.Unsupported:
|
case *types.Unsupported:
|
||||||
// No-op
|
// No-op
|
||||||
|
@ -167,6 +177,13 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
|
||||||
default:
|
default:
|
||||||
return errUnsupported
|
return errUnsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if w.idleStop != nil {
|
||||||
|
w.idleStop = make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
w.idleDone <- w.client.idle.IdleWithFallback(w.idleStop, 0)
|
||||||
|
}()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue