Repository navigation
The publisher's assets held through the loading cache - #1375
Draft
jwrosewell wants to merge 6 commits into
Draft
jwrosewell wants to merge 6 commits into
jwrosewell wants to merge 6 commits into
Conversation
Core gains source_cache.rs, which keeps each address's record of what the origin's responses vary on and a copy under each request's values for those headers, both through the loading cache, so requests for an address share one load and a copy is served only to a request whose values match, and asset_cache.rs, which is what a kept asset holds and the address it is held under. Both are selected by one table, [cache.assets], which CacheSettings lists after [cache.robots-txt], so a deployment names the module whose loading cache holds its assets as it does for robots.txt, and a build that links one takes it without a line in the document. Nothing holds an asset yet. The publisher path does in the next commit.
Every GET that is not a page is looked for in the asset cache before the origin is fetched, under the publisher's prefix and the asset's address, and a copy found is served as the origin's response would be, with an Age that counts from the origin's. A miss loads once however many requests ask at the same moment, keeps the response as the origin sent it when it may be shared, and hands a response that may not be shared back to the request whose load fetched it, so that request is served from one fetch and the requests that follow fetch their own for a minute rather than wait. What is never kept: anything but a 200, HTML, a response carrying Set-Cookie, one whose cache policy says private, no-store or no-cache or gives no lifetime, one that varies on * or on Cookie, one larger than a copy holds, and the answer to a request carrying Authorization. The record of what an address varies on and the copies are two caches selected by the one [cache.assets] table, and a deployment whose selected cache keeps nothing asks the origin as before.
…isher's assets are A file served through an asset route, under [[proxy.asset_routes]], streamed from its origin on every request, however many readers and instances asked for it, while a file the publisher's own origin sends was held through the loading cache. The route handler now looks for a copy under the same two caches [cache.assets] selects before it asks the origin, and keeps the origin's answer the way the publisher path keeps an asset: under what the origin says it varies on, for the lifetime its cache policy gives, served with the headers that describe it and an Age that counts from the origin's. The key carries the route's origin and prefix, so two routes to one address keep their own copies. Nothing is kept that may not be shared, by the same rules, and a request a copy cannot answer is not served one: anything but a GET, a request carrying Authorization, a conditional header or a range, one that names no host, and any request while the selected cache keeps nothing. An answer the platform's image optimizer makes is not kept either, because the platform holds it. An answer that may not be shared is served to the request whose load fetched it, from that one fetch. The publisher path's asset helpers are open to the rest of core so the route handler shares them, and the memory loading cache the publisher's tests used lives in the platform's test support so the route's tests use it too. Four tests cover an answer held and served to the next request with one origin call, an answer carrying Set-Cookie fetched for each request, a range request fetched rather than served a copy, and nothing held while no loading cache keeps values. The guide documents [cache.assets] beside [cache.robots-txt], with what is held and what never is, and the changelog says what the asset cache adds.
A body that outgrows a copy while it is read is handed back as what was read and then the rest. A response whose Vary no longer matches its record is served to the request that fetched it. Both were dropped, and that request asked the origin a second time. The asset caches run their loads in the request that started them, and an asset route refuses a copy to a request whose Cache-Control asks for the origin, as the publisher path does. The two lookups share one function, the origin checks the template cache and asset cache share are one helper, the three length-prefixed hashes share one, and the tests use the memory loading cache and the shared test services. The docs describe the copy and its key as they are built today.
This branch has not been deployed
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.
Summary
Changes
crates/trusted-server-core/srcdocs/guideCHANGELOG.mdcrates/trusted-server-adapter-axum/testsCloses
Closes #1324
Test plan
CI: 19 of 19 checks green, the fork's CI on f6e598f (jwrosewell#29).
cargo test-fastly && cargo test-axumcargo clippy-fastly && cargo clippy-axumcargo fmt --all -- --checkcd crates/trusted-server-js/lib && npx vitest runcd crates/trusted-server-js/lib && npm run formatcd docs && npm run formatcargo build --package trusted-server-adapter-fastly --release --target wasm32-wasip1fastly compute serveChecklist
unwrap()in production code (clippy deniesunwrap_usedin CI)logmacros as AGENTS.md asks (notprintln!)On top of the geo module called with the request (#28). Issue: #1324.
What this adds
What changes.
Every response the publisher's origin sends that is not a page, and every answer of an asset route under
[[proxy.asset_routes]], is held through the loading cache (#19), so an asset is fetched once however many readers and instances ask for it at the same moment, and the copy in the host's shared store answers every instance until the origin's own lifetime ends.A deployment that names no module in
[cache.assets]takes the one loading cache module the build links, as[cache.robots-txt]does, and a build that links none holds nothing and fetches every asset from the origin, which is what happens today.How it works.
Varynames, and that record is held in the loading cache like any other value. A later request for the address reads the record and is served the copy kept under its own values for those headers, as RFC 9111 section 4.1 describes. Requests for an address no record covers share one load.assets-varyandassets, so the loading cache module keeps a memory layer for each, and both are selected by the one[cache.assets]table. Core declares both as its own, besiderobots-txt, so a module cannot declare either.GET, anything but a200, HTML (a page is a template or nothing), a response carryingSet-Cookie, a response whose cache policy saysprivate,no-storeorno-cacheor gives no lifetime, a response that varies on*or onCookie, a response larger than a copy holds (1 MiB), and the answer to a request carryingAuthorization, a conditional header, a range, or aCache-Controlthat asks for the origin (no-cache,no-store,min-freshor a nonzeromax-age).Agethat counts from the origin's, and the fetch and serve entries of the configuration run on it as they run on a fetched response.Why
A deployment with the platform's cache in front of it already has its assets held there. A deployment with nothing in front of it, and one whose fetch phase rewrites an asset before a reader sees it, fetches every asset on every page from the publisher's origin every time, and every instance does. The loading cache was declared so that each feature that holds answers selects the cache that holds them, and assets are the feature it was declared for after robots.txt.
What breaks
Nothing for a deployment that names no
[cache.assets]table in a build that links no loading cache module. A deployment whose build links one starts holding shareable assets for the lifetime the origin gives them, so a change at the origin shows after that lifetime, as it does behind any shared cache.The commits
[cache.assets]Cache-Control, shared test and hashing helpersCI being read on f6e598f.
What is not in this pull request
[publisher.origin_personalization]), which separates copies the origin's ownVarydoes not. Later, with its tests./proxyfirst-party route, which rehosts third party assets named in a page. It streams, and on Fastly the platform's cache holds it.