Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Caching: give caches more flexibility to calculate Age #1110

Open
ethanresnick opened this issue Sep 30, 2023 · 0 comments
Open

Caching: give caches more flexibility to calculate Age #1110

ethanresnick opened this issue Sep 30, 2023 · 0 comments

Comments

@ethanresnick
Copy link

Imagine there's an origin with a chain of caches in front of it, and the caches' clocks are known to be well-synchronized with the origin's clock — perhaps because the caches and the origin are run by the same organization. In that case, the caches could compute a much more accurate Age value by not using the formulas in RFC 9111. However, in order to do so, they would have to exploit this knowledge about their clocks being synchronized, and the RFC doesn't seem to allow them to do that. So, I think giving caches a bit latitude for these cases, so they can compute a more accurate Age while remaining spec-compliant, would be nice.

Here's an example scenario to motivate this:

  • The network path is User Agent -> Cache A -> Cache B -> Cache C -> Origin.
  • The network latency is 50ms between each hop (100ms round-trip)
  • When the origin receives a GET /something-expensive request, it forms its response by reading a bunch of data and doing heavy computations on that data; this whole process takes 5 seconds. In order to ensure that the data isn't changing during the course of the computation, the origin takes a snapshot of the data at the beginning of the request, and reads from that snapshot throughout. Because the state of the HTTP resource is a function of this underlying data, the origin's response reflects the state of the resource at the time of the snapshot, so it uses the time of the snapshot as the response Date.

Now, assume the user agent requests GET /something-expensive and there's a cache miss at each cache, so the request gets forwarded all the way to the origin. When the origin receives the request from Cache C, it responds 5 seconds later. When that response reaches Cache C, it won't have an Age header, but Cache C will have observed a 5.1s response_delay (accounting for the 100ms round-trip time between Cache C and the origin). So, using the current_age formula, Cache C will return Age: 5. Then, Cache B sees an age_value of 5 from Cache C's response but it also measures a response_delay of 5.2s. So, the Age value it sends in its response to Cache A is 10s. Finally, Cache A repeats this process and concludes that the response is 15s old, which it returns to the user agent in the Age. In reality, the response is only ~5.15s old at this point, not 15s!

There's a mix here of "double counting" and counting some things that shouldn't be part of the age at all (e.g., the inbound latency from Cache A to the origin). But I think these are well-known limitations to using a response_delay-based age — and they're unavoidable if the servers can't trust each other's clocks.

The point of this issue, though, is about giving the cache more flexibility when the origin's clock is known to be reasonably synchronized with the cache's. In those cases, just using apparent_age will give better results. Right now, though, apparent_age can only be used to increase the computed current_age, via the formula:

corrected_initial_age = max(apparent_age, corrected_age_value);

If some conditions hold — and I'm not sure exactly how to formalize all the conditions where this would apply — it seems like caches ought to be able to use the apparent_age as the corrected_initial_age, or at least heavily bias the corrected_initial_age toward the apparent_age.

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

No branches or pull requests

1 participant