feat: never-evicting per-entry store behind the API cache - #638
Merged
Conversation
The persistent cache (issue #570) only captured what was still in the in-memory caches at save time, so their 24h idle expiry propagated into the snapshot: pages not visited for a day of runtime came back from a restart with a blank loading state instead of their previous content. A per-entry store (a directory of one file per query response or map, next to the snapshot file) now forms a persistent tier that never evicts: every successful fetch overwrites its entry, and a memory miss in the retrieval paths falls through to the store, re-inserting the entry with its original timestamp so the usual staleness logic serves the stored content right away while re-querying in the background. The store is backfilled from the snapshot file at startup; the in-memory caches keep their bounded size and idle expiry. Surefire now disables cache persistence, as tests starting a WicketApplication were reading and writing the developer's real snapshot in ~/.nanopub — permanent pollution with a store that never evicts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
🎉 This PR is included in version 5.12.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #570. The persistent cache only captured what was still in the in-memory caches at save time, so their 24h idle expiry propagated into the snapshot: space and maintained-resource pages not visited for a day of runtime came back from a restart with a blank loading state instead of their previous content (user pages mostly escaped this because their few pages are visited often and their cache keys are stable).
What this adds
<apiCacheFile>.d/, default~/.nanopub/nanodash-api-cache.ser.d/) with one small file per query response or map, named by a SHA-256 of the cache id. Every successful fetch overwrites its entry (atomic tmp+move). This tier never evicts — content that once arrived stays available until a re-fetch replaces it.retrieveStaleResponse,retrieveResponseSync,retrieveResponseAsync, andretrieveMapfall through to the store and re-insert the entry with its original timestamp, so the existing stale-while-revalidate logic serves the stored content immediately while re-querying in the background. No display-layer changes needed.NANODASH_API_CACHE_FILE=none— tests starting aWicketApplicationwere reading and writing the developer's real snapshot in~/.nanopub, which would become permanent pollution with a never-evicting store.Verified
Trade-off: the store grows monotonically (a few KB per distinct query+params ever issued); housekeeping can be layered on later without touching the read/write paths. Not addressed here: the multi-ref representative-root flip still makes a space page cold once per flip, since the new
root_npcache key has never been fetched — possible follow-up is a seed fallback to other known ref roots.🤖 Generated with Claude Code