fetch: respect HTTP Cache-Control headers with TTL-based invalidation (#91729)#92322
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
| impl Default for FetchClientConfig { | ||
| fn default() -> Self { | ||
| Self { | ||
| min_cache_control_secs: 60 * 60, |
There was a problem hiding this comment.
should be a duration
Tests Passed |
Merging this PR will not alter performance
Comparing Footnotes
|
97f761f to
1ca16ac
Compare
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📎 Tarball URL |
c338444 to
a88b102
Compare
1ca16ac to
805b915
Compare
a88b102 to
f5f9dc0
Compare
805b915 to
68f3514
Compare
68f3514 to
d6da110
Compare
f5f9dc0 to
0cae08f
Compare
0cae08f to
70da271
Compare
83fb56d to
708b5d2
Compare
70da271 to
781db31
Compare
781db31 to
0522d66
Compare
708b5d2 to
746c98f
Compare
0522d66 to
00769ef
Compare
746c98f to
7c5aad0
Compare
00769ef to
a550e51
Compare
7c5aad0 to
8524df5
Compare
a550e51 to
c7c7689
Compare
8524df5 to
04c1db8
Compare

Summary
This is a re-application of the HTTP fetch part of #91729. Stacked on #92358.
Fix fetch to respect HTTP
Cache-ControlheadersPreviously,
fetchresults were cached indefinitely, meaning results would never be refreshed (unless the cache was invalidated). Now they aresession_dependentwith a TTL to ensure we respect HTTP cache settings (e.g. Google Fonts withmax-age=86400).New two-task pattern:
fetch_inner(NOTsession_dependent): Performs the HTTP request, grabs anInvalidatorfor itself, and returns the response + invalidator + absolute deadline. Cached across sessions.fetch(network,session_dependent): Reads the cachedfetch_innerresult and spawns a timer to invalidate when the TTL expires.On warm cache restore,
fetchre-executes (session-dependent), reads the persisted deadline fromfetch_inner's cached result, computes remaining TTL, and spawns a timer — no HTTP request unless the TTL has already expired. Mid-session, the timer fires and triggers a re-fetch.Error handling: On fetch failure,
fetch_innertakes a dependency onCompletion::session_dependent()so transient errors (network down, DNS failure) are retried on the next session without busy-looping.Test Plan
3 new integration tests in
turbo-tasks-fetch/tests/fetch.rs:ttl_invalidates_within_session— mock server returnsmax-age=1, body changes, verifies re-fetch after TTLttl_invalidates_on_session_restore— fetches with TTL, stops TT, waits for expiry, warm restores with new TT, verifies re-fetcherrors_retried_on_session_restore— server returns 500, stops TT, fixes server, warm restores, verifies successCloses NEXT-