Skip to content

Assets held through the loading cache #1324

Open

Description

@jwrosewell

Stacks on the geo module called with the request (#1321). One of the additions listed in #777.

What changes

Every response the publisher's origin sends that is not a page is held through the loading cache (#1282), 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.

[cache.assets]
module = "51degrees"
memory_seconds = 5
store_seconds = 3600

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

  • A copy is kept under what the origin says it varies on. The first response for an address records the request headers its Vary names, 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.
  • What is never kept, whatever the settings say: anything but a GET, anything but a 200, HTML (a page is a template or nothing), a response carrying Set-Cookie, a response whose cache policy says private, no-store or no-cache or gives no lifetime, a response that varies on * or on Cookie, a response larger than a copy holds (1 MiB), and a request carrying Authorization. A response that may not be shared is handed back to the request whose load fetched it, so that request is served from one fetch, not two, and the requests that follow fetch their own for a minute rather than wait.
  • A copy is served as the origin's response would be, with the headers that describe the bytes, an Age that counts from the origin's, and the fetch and serve entries of the configuration run on it as they run on a fetched response.
  • The publisher's declared rule. An origin can vary on a cookie, a header or a query parameter without naming it, and only the publisher knows that, so the publisher declares it in [publisher.origin_personalization]. The declaration separates the copies the cache keeps and names those inputs in the response's Vary, so a cache anywhere in the path separates readers the same way. No declaration means the origin's own headers decide.
  • Each publisher's copies are its own. Every key starts with the publisher's prefix, so two publishers sharing a store never share a copy.

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.

How it was verified

CI on the fork. The tests cover one origin call for two requests of one asset with the second served the copy, each not-shareable case, the hand-back, the declared rule's cases, and the integration crate's guard, which runs two rounds through a deployment's cache selection and fails if the second round asks the origin.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions