Skip to content

fix(config): cache read no mutation#1256

Open
mvanhorn wants to merge 1 commit intofloatpane:masterfrom
mvanhorn:fix/1251-cache-read-no-mutation
Open

fix(config): cache read no mutation#1256
mvanhorn wants to merge 1 commit intofloatpane:masterfrom
mvanhorn:fix/1251-cache-read-no-mutation

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

@mvanhorn mvanhorn commented May 8, 2026

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.

Tests

  • go build ./... clean
  • go test ./... passes (config, daemon, daemonclient, daemonrpc, fetcher, internal/httpclient, internal/threading, pgp, plugin, sender, tui, view all green)
  • go vet ./... clean
  • gofmt -l config/cache.go clean

Closes floatpane#1251

GetCachedEmailBody is a read operation but updated LastAccessedAt
and rewrote the cache file on every hit, violating the
read-doesn't-mutate boundary called out in floatpane#1251. main.go calls
GetCachedEmailBody twice per email view (in UpdatePreviewMsg and
ViewEmailMsg) and both call sites already chase the cached read
with SaveEmailBody, which is the function responsible for stamping
LastAccessedAt and persisting. Removing the duplicate work here
also removes one disk write per email view.

Drops the two lines flagged in the issue (config/cache.go:505-506)
and adds a one-line note above the function pointing readers at
SaveEmailBody as the access-time owner.
@mvanhorn mvanhorn requested a review from a team as a code owner May 8, 2026 10:54
@floatpanebot floatpanebot added area/config Configuration / settings bug Something isn't working ci CI / build pipeline labels May 8, 2026
Copy link
Copy Markdown
Member

@floatpanebot floatpanebot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mvanhorn! Please fix the following issues with your PR:

  • Title: Is too long (76 characters). The PR title must be strictly under 40 characters.

@mvanhorn mvanhorn changed the title fix(config): GetCachedEmailBody no longer mutates cache state (closes #1251) fix(config): cache read no mutation May 8, 2026
@floatpanebot floatpanebot dismissed their stale review May 8, 2026 11:27

Formatting issues have been resolved. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Configuration / settings bug Something isn't working ci CI / build pipeline

Projects

None yet

Development

Successfully merging this pull request may close these issues.

read function should not modify cache state

3 participants