Skip to content

A bare-URI purge of a child does not bust a parent embedding a specific variant of it #257

Closed

Description

@koriym

Follow-up from #255 / #256.

Gap

CacheDependency::depends($from, $to) (src/CacheDependency.php:31-46) copies the child's entire own Surrogate-Key header verbatim into the embedding parent's header, plus the child's plain UriTag($to->uri). It never independently adds the child's BaseUriTag group tag.

This is only a real gap for a plain #[Cacheable] value-type child: its own response never carries a Surrogate-Key header at all (QueryRepository::doPut() adds the group tag only to a local variable passed to saveEtag(), never to $ro->headers), so depends() has nothing to copy, and a bare-URI purge of that child does not bust a parent embedding a specific variant of it.

A #[CacheableResponse]/#[DonutCache] child does not have this gap: it writes its own group tag into its own Surrogate-Key header at save time (doPutStatic/doPutDonut), and depends()'s verbatim header copy already carries it to the parent for free.

Verified directly with CacheDependency::depends() called on a child fetched at a non-bare variant (?page=2): for a donut/response-type child, the parent's resulting header contains the group tag but not the child's bare plain tag, confirming the group tag specifically (not the plain tag) is what a later bare-URI purge of the child would use to reach the parent - and that it already does, for this flavor. For a plain value-type child under the same test, the parent's header contains neither the group tag nor anything from it beyond the child's own exact-variant plain tag.

Fix direction

Add ($this->baseUriTag)($to) to the merge inside CacheDependency::depends(), only when $to is a value-type resource that doesn't already carry a group tag in its own header (donut/response children already do, so this stays a no-op for them, not a duplicate). Needs CacheDependency to gain a BaseUriTagInterface constructor dependency, a fixture (a parent embedding a plain #[Cacheable] value-type child at a specific query variant), and a regression test (purge the child's bare form, assert the parent is also busted). Kept out of #256 to avoid widening that PR's scope after its own two review-driven iterations.

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