From 22f6eeacd7ab650396aca86e5daa07c1a2c4157c Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 27 Jun 2018 02:38:46 +0100 Subject: [PATCH] Horrible hack for bad architecture --- internal/imap/uidlist/uidlist.go | 15 +++++++++-- internal/store/maildir.go | 46 ++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/internal/imap/uidlist/uidlist.go b/internal/imap/uidlist/uidlist.go index 9f3a36a..cfce21c 100644 --- a/internal/imap/uidlist/uidlist.go +++ b/internal/imap/uidlist/uidlist.go @@ -143,7 +143,10 @@ func (l *List) Append(filenames ...string) error { log.Printf("Adding entry: %#v", entry) l.entries = append(l.entries, entry) - l.header.NextUID = l.header.NextUID + 1 + + log.Printf("NextUID: %v", l.header.NextUID) + l.header.NextUID++ + log.Printf("NextUID: %v", l.header.NextUID) // Try to write them all, at least // FIXME: we don't bubble up errors when we should @@ -191,6 +194,9 @@ func (l *List) parse() error { l.mutex.Lock() defer l.mutex.Unlock() + log.Printf("Parsing %v", l.filename) + defer func() { log.Printf("Finished parsing %v", l.filename) }() + file, err := os.Open(l.filename) if err != nil { return err @@ -212,6 +218,7 @@ func (l *List) parse() error { // Now parse each additional line entries := []Entry{} + for r.Scan() { entry, err := ParseEntry(r.Text()) if err != nil { @@ -221,13 +228,17 @@ func (l *List) parse() error { // If NextUID is out of date in the file, ignore it. We never want to // re-use a seen UID + log.Printf("l.header.NextUID: %v", l.header.NextUID) if entry.UID >= l.header.NextUID { - l.header.NextUID++ + log.Printf("Incrementing as entry with UID %v is greater", entry.UID) + l.header.NextUID = entry.UID + 1 } + log.Printf("l.header.NextUID: %v", l.header.NextUID) } l.header = header l.entries = entries + log.Printf("list: %#v", l) return nil } diff --git a/internal/store/maildir.go b/internal/store/maildir.go index 31873f7..f1a3659 100644 --- a/internal/store/maildir.go +++ b/internal/store/maildir.go @@ -5,6 +5,7 @@ import ( "net/mail" "os" "path/filepath" + "sync" "github.com/luksen/maildir" @@ -55,21 +56,38 @@ func (c *concrete) CreateMaildir(m *Maildir) error { } if m.uids == nil { - uids, err := uidlist.Create(m.directory) - if err != nil { - // FIXME: this leaves a dangling Maildir - return err + uidsLock.Lock() + defer uidsLock.Unlock() + + if uidsCache[m.Rel()] == nil { + + uids, err := uidlist.Create(m.directory) + if err != nil { + // FIXME: this leaves a dangling Maildir + return err + } + uidsCache[m.Rel()] = uids } - m.uids = uids + m.uids = uidsCache[m.Rel()] } return nil } +// Ugh +// FIXME: multiple sessions get different Maildir instances, so breaking any +// hope at locking (sigh) +var ( + uidsLock sync.Mutex + uidsCache map[string]*uidlist.List +) + +func init() { + uidsCache = make(map[string]*uidlist.List) +} + func (c *concrete) FindMaildir(account Account, name string) (Maildir, error) { - // FIXME: multiple IMAP sessions get different Maildir instances, so breaking - // any hope at locking (sigh) m := Maildir{ Account: account, Name: name, @@ -81,11 +99,17 @@ func (c *concrete) FindMaildir(account Account, name string) (Maildir, error) { return Maildir{}, errors.New("not found") } - uids, err := uidlist.Open(m.directory) - if err != nil { - return Maildir{}, err + uidsLock.Lock() + defer uidsLock.Unlock() + if uidsCache[m.Rel()] == nil { + uids, err := uidlist.Open(m.directory) + if err != nil { + return Maildir{}, err + } + uidsCache[m.Rel()] = uids } - m.uids = uids + + m.uids = uidsCache[m.Rel()] return m, nil }