diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2023-04-30 12:56:10 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2023-05-16 17:07:50 +0200 |
commit | 6b6aaf3ae131971d05ab3f849ea3db14c6a6e055 (patch) | |
tree | 00f9055556388cf1396af6da84ef0b5b59814efe /worker/imap | |
parent | e8089e7d8f6065031814bf7d80be043536e09fe7 (diff) | |
download | aerc-6b6aaf3ae131971d05ab3f849ea3db14c6a6e055.tar.gz |
headers: enable partial header fetching
Enable partial header fetching by creating config values for headers to
specifically include, or specifically exclude. The References field will
always be fetched, regardless of the include list. Envelope data is
always fetched, but is not shown with :toggle-headers, since it isn't in
the RFC822 struct unless explicitly included in the list.
Partial headers can break the cache on changes. Update the cache tag key
to include the state of the partially-fetched headers.
Partial header fetching can have a significant performance increase for
IMAP, and for all backends a resource improvement. Some data to support
this is below. Gathered by opening aerc, selecting a mailbox with
approximately 800 messages and scrolling to the end.
Received measured with nethogs, RAM from btop
Received | RAM
-------------------------------------
All Headers | 9,656 kb | 103 MB
Minimum Headers | 896 kb | 36 MB
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/imap')
-rw-r--r-- | worker/imap/cache.go | 9 | ||||
-rw-r--r-- | worker/imap/configure.go | 2 | ||||
-rw-r--r-- | worker/imap/fetch.go | 16 | ||||
-rw-r--r-- | worker/imap/worker.go | 2 |
4 files changed, 25 insertions, 4 deletions
diff --git a/worker/imap/cache.go b/worker/imap/cache.go index a02f2cae..cf372154 100644 --- a/worker/imap/cache.go +++ b/worker/imap/cache.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "path" + "strings" "time" "git.sr.ht/~rjarry/aerc/lib/parse" @@ -42,6 +43,14 @@ var ( // initCacheDb opens (or creates) the database for the cache. One database is // created per account func (w *IMAPWorker) initCacheDb(acct string) { + switch { + case len(w.config.headersExclude) > 0: + headerTag := strings.Join(w.config.headersExclude, "") + cacheTag = append(cacheTag, headerTag...) + case len(w.config.headers) > 0: + headerTag := strings.Join(w.config.headers, "") + cacheTag = append(cacheTag, headerTag...) + } cd, err := cacheDir() if err != nil { w.cache = nil diff --git a/worker/imap/configure.go b/worker/imap/configure.go index a9689f68..1581794f 100644 --- a/worker/imap/configure.go +++ b/worker/imap/configure.go @@ -60,6 +60,8 @@ func (w *IMAPWorker) handleConfigure(msg *types.Configure) error { w.config.user = u.User w.config.folders = msg.Config.Folders + w.config.headers = msg.Config.Headers + w.config.headersExclude = msg.Config.HeadersExclude w.config.idle_timeout = 10 * time.Second w.config.idle_debounce = 10 * time.Millisecond diff --git a/worker/imap/fetch.go b/worker/imap/fetch.go index f209d7f0..8189e6aa 100644 --- a/worker/imap/fetch.go +++ b/worker/imap/fetch.go @@ -29,11 +29,19 @@ func (imapw *IMAPWorker) handleFetchMessageHeaders( return } log.Tracef("Fetching message headers: %v", toFetch) + hdrBodyPart := imap.BodyPartName{ + Specifier: imap.HeaderSpecifier, + } + switch { + case len(imapw.config.headersExclude) > 0: + hdrBodyPart.NotFields = true + hdrBodyPart.Fields = imapw.config.headersExclude + case len(imapw.config.headers) > 0: + hdrBodyPart.Fields = imapw.config.headers + } section := &imap.BodySectionName{ - BodyPartName: imap.BodyPartName{ - Specifier: imap.HeaderSpecifier, - }, - Peek: true, + BodyPartName: hdrBodyPart, + Peek: true, } items := []imap.FetchItem{ diff --git a/worker/imap/worker.go b/worker/imap/worker.go index f9a722e6..f46f39d6 100644 --- a/worker/imap/worker.go +++ b/worker/imap/worker.go @@ -43,6 +43,8 @@ type imapConfig struct { insecure bool addr string user *url.Userinfo + headers []string + headersExclude []string folders []string oauthBearer lib.OAuthBearer xoauth2 lib.Xoauth2 |