Skip to content

Fix 92x compatibility cache revalidation - #13611

Draft
traeak wants to merge 5 commits into
apache:masterfrom
traeak:92x_compat
Draft

Fix 92x compatibility cache revalidation#13611
traeak wants to merge 5 commits into
apache:masterfrom
traeak:92x_compat

Conversation

@traeak

@traeak traeak commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Follow on to #12271 and #12283

proxy.config.http.cache.try_compat_key_read could find an object stored
under the ATS 9.2 cache key but never do anything useful with it. The write
that would carry a revalidation or an update is a create on the current key
rather than an update of the legacy vector, so the cache silently discarded
it — 304s, header updates and negative revalidating all became no-ops that
still reported success. Separately, the 9.2 key was reproduced incorrectly
for any path containing ;, so those objects were never found at all.

  • Revalidate compatibility-key objects without conditional headers, so the
    origin returns a full response and the existing write path migrates the
    object to the current key.
  • Reproduce the real 9.2 key, and skip the second lookup where the two keys
    provably converge.
  • Leave the legacy copy to age out rather than deleting it: nothing at the
    state-machine layer reports that the new object reached disk, so deleting
    on the tunnel's write-complete event loses the object whenever the write
    is later rejected.

NOTE: As part of cache migration, if a 92x header is detected any IMS headers to parent are stripped and the asset is freshly pulled from parent. This will cause an increase in parent bandwidth as stale objects will be repulled instead of refreshed.

@traeak traeak self-assigned this Sep 1, 2026
@traeak traeak added the Cache label Sep 1, 2026
@traeak
traeak requested a lite review from Copilot September 1, 2026 17:42

This comment was marked as outdated.

@traeak
traeak marked this pull request as ready for review September 1, 2026 19:03
Copilot AI review requested due to automatic review settings September 1, 2026 19:03

This comment was marked as resolved.

Copilot AI review requested due to automatic review settings September 1, 2026 20:26

This comment was marked as outdated.

Copilot AI review requested due to automatic review settings September 1, 2026 21:24

This comment was marked as outdated.

Copilot AI review requested due to automatic review settings September 1, 2026 21:58

This comment was marked as outdated.

@traeak
traeak marked this pull request as draft September 2, 2026 15:43
@traeak
traeak requested a lite review from Copilot September 8, 2026 12:47

This comment was marked as resolved.

@traeak
traeak requested a lite review from Copilot September 8, 2026 13:12

This comment was marked as resolved.

@traeak
traeak requested a lite review from Copilot September 8, 2026 15:32

This comment was marked as resolved.

@traeak
traeak requested a lite review from Copilot September 8, 2026 16:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comment on lines +2803 to +2814
Two costs come with enabling this. Every cache miss performs a second
lookup, so a tier with a low hit ratio roughly doubles its cache lookup
load for the duration. And an object found under the previous key is
revalidated *without* conditional headers, because a ``304`` cannot be
applied to it: the write that would carry the update is a create under the
new key rather than an update of the old one. The origin therefore returns
the full response, which is stored under the new key. The copy under the
previous key is left in place to age out on its own, since nothing reports
that the new object reached disk; it stops being read as soon as the new key
resolves, so both keys briefly hold the object. Each object pays this once,
but on a large cache the aggregate is a bandwidth event worth sizing before
enabling the setting in production.
Comment on lines +2589 to +2599
if (s->state_machine != nullptr && should_use_compatibility_cache_key(s->state_machine->compatibility_cache_lookup)) {
// build_request() already strips the client's conditionals for a request it
// expects to cache, but keeps them when the request does not look cacheable
// or when cache_when_to_revalidate is 4. Either way the origin could answer
// 304, so drop them here too. The client still gets its 304: a conditional
// client request is matched against the full response in
// handle_cache_operation_on_forward_server_response().
TxnDbg(dbg_ctl_http_trans, "compatibility key hit, revalidating without conditional headers");
HttpTransactHeaders::remove_conditional_headers(&s->hdr_info.server_request);
return;
}
Comment on lines +182 to +196
/// Whether this lookup addresses the cache with the previous (9.2) key.
inline bool
should_use_compatibility_cache_key(CompatibilityCacheLookup lookup)
{
return lookup == CompatibilityCacheLookup::COMPAT_CACHE_LOOKUP_92;
}

/// The object info to hand to a cache write, which a compatibility read must not
/// carry: it belongs to the legacy key and would turn the write into an update
/// of a vector the canonical key does not have.
inline CacheHTTPInfo *
cache_write_info_for_lookup(CompatibilityCacheLookup lookup, CacheHTTPInfo *object_read_info)
{
return should_use_compatibility_cache_key(lookup) ? nullptr : object_read_info;
}
Comment thread src/proxy/http/HttpSM.cc
Comment on lines +5286 to +5296
// The URL this transaction looks up in the cache. A redirect follow looks up the
// redirected URL rather than the original, unless the transaction is configured
// to keep the original cache key.
URL *
HttpSM::cache_lookup_url()
{
if (t_state.redirect_info.redirect_in_process && !t_state.txn_conf->redirect_use_orig_cache_key) {
return t_state.hdr_info.client_request.url_get();
}
return t_state.cache_info.lookup_url;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants