## What?
Closes #1251
`GetCachedEmailBody` is a read operation but it was stamping
`LastAccessedAt` on the matched entry and rewriting the body cache file
on every hit, violating the read/write boundary the issue calls out.
Drops the two flagged lines (`config/cache.go:505-506`) and adds a
one-line note above the function that `SaveEmailBody` is the access-time
owner.
## Why?
The issue's analysis is correct: every email view path in `main.go`
already chases `GetCachedEmailBody` with `SaveEmailBody`, which sets
`LastAccessedAt = time.Now()` on the entry it persists. That keeps the
LRU-style eviction in `evict` (sorted by `LastAccessedAt`) working
unchanged, with one fewer disk write per email view.
I traced both call sites to verify eviction recency is preserved on
cache hits:
- `main.go:707-744` (UpdatePreviewMsg): cache hit returns
`PreviewBodyFetchedMsg{Err: nil}`. The handler at `main.go:746-779` runs
`config.SaveEmailBody` whenever `msg.Err == nil`, which updates
`LastAccessedAt` (`config/cache.go:552`).
- `main.go:1247-1278` (ViewEmailMsg): cache hit returns
`EmailBodyFetchedMsg{Err: nil}`. The handler at `main.go:1282-1328` runs
`config.SaveEmailBody` whenever `msg.Err == nil`, same path.
So an email the user repeatedly opens still bumps to the front of the
eviction queue on every open; the work just happens in `SaveEmailBody`
(which already exists) instead of duplicating it inside
`GetCachedEmailBody`.
@@ -495,6 +495,8 @@ func saveEmailBodyCache(cache *EmailBodyCache) error {
}
// GetCachedEmailBody returns the cached body for a specific email, or nil if not cached.
+// LastAccessedAt is updated by SaveEmailBody, not here -- a read should not
+// mutate cache state.
func GetCachedEmailBody(folderName string, uid uint32, accountID string) *CachedEmailBody {
cache, err := LoadEmailBodyCache(folderName)
if err != nil {
@@ -502,8 +504,6 @@ func GetCachedEmailBody(folderName string, uid uint32, accountID string) *Cached
}
for i, b := range cache.Bodies {
if b.UID == uid && b.AccountID == accountID {
- cache.Bodies[i].LastAccessedAt = time.Now()- _ = saveEmailBodyCache(cache)
return &cache.Bodies[i]
}
}