BreadcrumbBuilder::applies() mismatch with cacheability metadata

Created on 5 May 2016, about 8 years ago
Updated 18 June 2024, 9 days ago

Problem/Motivation

Breadcrumb builders are called in a specific order, the first one that returns a valid Breadcrumb object from its build() method is the one that will be returned from the manager. Before a builder is called, we first check its applies() method and only if that returns TRUE do we call build().

The problem lies within the fact that the applies check might introduce variability that needs to be represented by a cache context, but is not unless it returns TRUE. At that point does the build() method add the right cacheable metadata to the breadcrumb result. This is wrong, though, because a negative outcome also needs to have said cacheable metadata.

You can see how this breaks in #3452181-7: VariationCache needs to be more defensive about cache context manipulation to avoid broken redirects β†’ , comments 7 through 9.

Proposed resolution

Pass cacheable metadata to the applies() method so that it can properly set its variability (cache contexts) and dependencies.

Remaining tasks

Review MR and commit

User interface changes

N/A

API changes

BreadcrumbBuilderInterface::applies() now takes a second argument CacheableMetadata $cacheable_metadata

Data model changes

N/A

πŸ› Bug report
Status

RTBC

Version

11.0 πŸ”₯

Component
BaseΒ  β†’

Last updated about 3 hours ago

Created by

πŸ‡ΊπŸ‡ΈUnited States jhodgdon Spokane, WA, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    This surfaced as part of some extra hardening I'm trying to introduce into VariationCache: πŸ› VariationCache needs to be more defensive about cache context manipulation to avoid broken redirects Active

    Re #11:

    Does this mean we need to run through all breadcrumb builders?

    No, because they always run in the same order. So as long as we clear the cache when a new builder is introduced into the list, we're fine.

    Let's say you have 3 builders, the 1st applies() check varies by route, the 2nd by domain and the 3rd by user roles (for whatever reason). Then, as long as the first in the list applies, all we need to care about is the 'route' cache context. Only when the first one ever fails and we fall back to the second one, do add the url.site cache context. At this point, VariationCache will write a CacheRedirect at the current value for 'route', setting the 'url.site' cache contexts. Then, if both the 1st and 2nd applies() check fail, will another CacheRedirect be created to allow VC to store items from the 3rd builder.

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium
    The only other way that I see is that we introduce a new applies() method on a new interface that can return something like AccessResult. A binary result + cacheablity metadata.

    This was my first thought here - new interface, extend the old interface. We could also pass in an optional CacheableMetadata object into the applies method so the return doesn't need to change.

    Why note use the deprecation policy guideline on introducing a new argument to an existing signature? https://www.drupal.org/about/core/policies/core-change-policies/drupal-d... β†’

    I'll try that approach to allow a 2nd argument to be passed to applies().

  • Issue was unassigned.
  • Status changed to Needs review 14 days ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium
  • Pipeline finished with Failed
    14 days ago
    Total: 131s
    #198688
  • Pipeline finished with Failed
    14 days ago
    Total: 132s
    #198687
  • Pipeline finished with Failed
    14 days ago
    #198690
  • Status changed to Needs work 14 days ago
  • The Needs Review Queue Bot β†’ tested this issue.

    While you are making the above changes, we recommend that you convert this patch to a merge request β†’ . Merge requests are preferred over patches. Be sure to hide the old patch files as well. (Converting an issue to a merge request without other contributions to the issue will not receive credit.)

  • Pipeline finished with Failed
    14 days ago
    Total: 648s
    #198708
  • Status changed to Needs review 14 days ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Should go green now. From the other issue:

    This caused StandardPerformanceTest to fail as there are now 2 more cache gets, which makes sense because we added a cache context.

  • Pipeline finished with Failed
    14 days ago
    Total: 583s
    #198775
  • Pipeline finished with Failed
    14 days ago
    Total: 548s
    #198793
  • Pipeline finished with Failed
    14 days ago
    Total: 516s
    #198832
  • Pipeline finished with Success
    14 days ago
    Total: 512s
    #198843
  • Status changed to Needs work 11 days ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    The issue summary mentions "Revert or fix #2699627: url.path cache context for breadcrumbs is unnecessarily granular β†’ " can I ask which one it is? Maybe this can be flushed out more. Don't think this is an API or model change so put those as N/A

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    The MR is the correct approach, it's just that the issue summary needs severe updating.
    The new approach is #10, #36 and #37

    In essence: Allow the applies() method to set cacheability. Because the breadcrumb builders run in the same order every time and because only one can build the actual breadcrumb, we don't need to care about ALL builder's cacheable metadata, just the data up until the builder that actually applies.

    I'll try to update the IS tomorrow.

  • πŸ‡³πŸ‡±Netherlands mike.vindicate

    Attached a patch that can be used for Drupal 10.2. Thanks for fixing the issue.

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Please don't convert MRs into patches as it creates a lot of unnecessary noise. Especially when the MR is still up for review and might change.

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium
  • Status changed to Needs review 10 days ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    @smustgrave Updated the IS to reflect the actual bug and how it should be fixed. The initial IS was just one case of running into it, but πŸ› VariationCache needs to be more defensive about cache context manipulation to avoid broken redirects Active exposes the problem in more detail as it also causes incorrect cache redirects to be written.

  • Status changed to Needs work 10 days ago
  • πŸ‡§πŸ‡ͺBelgium BramDriesen Belgium πŸ‡§πŸ‡ͺ

    Maybe because I'm tired, but I had a really hard time reading the doc block to try and understand what it was trying to say. Grammatically strange sentences and missing capital letters as well.

    Code wise not much to add to the review. Looks clean and the other comments are easy to read.

  • Status changed to Needs review 10 days ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Hopefully this is a bit easier on the eyes.

  • πŸ‡§πŸ‡ͺBelgium BramDriesen Belgium πŸ‡§πŸ‡ͺ

    Already better πŸ™‚

    The cacheable metadata to add to if your check varies by or depends on something

    Can't the "to" be removed? Or specify to what we're adding metadata?

    Anything you specified here does not have to be repeated in the build() method as it will be merged in automatically.

    Anything you have? ... merged automatically?

    I'm no native english speaker, but with above changes I suggested it would read easier to me.

  • Pipeline finished with Success
    10 days ago
    Total: 646s
    #202034
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Can't the "to" be removed?

    That would make it broken English. You have the infinite "to add" and then "to" as you're adding to something (the CacheableMetadata).

    Or specify to what we're adding metadata?

    This documentation is for the $cacheable_metadata parameter, so I think it should be clear that that's the thing you're adding to?

    Anything you specified here does not have to be repeated in the build() method as it will be merged in automatically.

    You can use "Anything you specify here" or "Anything you specified here", depending on whether you want it to read like a forward-looking suggestion or vice versa. I wouldn't use "have", though. If you want we can change it to the present tense.

    As for "merged in", it's because you merge whatever was specified into the final result. Because that sentence has no mention of "the final result", the "to" part of "into" is dropped. Example: John was about to walk into the river, as he walked in, he felt something sharp beneath his feet.

  • Status changed to RTBC 9 days ago
  • πŸ‡§πŸ‡ͺBelgium BramDriesen Belgium πŸ‡§πŸ‡ͺ

    Nah, it’s fine then πŸ˜‡ again, not a native speaker. πŸ˜‰

  • πŸ‡ΊπŸ‡ΈUnited States neclimdul Houston, TX

    I think I understand the reason of the change and it makes sense. Previously you'd have to return true from applies if you _might_ apply and then builder would have to do the actual check and apply the cache-ability. Yeah, that's a pretty big gotcha when building these builders.

    Looking at the merge, there's a lot of duplicate adding of the route to the cache-ability. I guess maybe this is a dumb question and probably well understood in the building of BreadcrumbManager but isn't varying by route kinda a baseline implied functionality for breadcrumb builders? That's why we pass the route_manager in right? Should the manager just include that by default and this change would only be used for more exotic cases?

    If it helps the discussion, and example where it doesn't cache by route in core is PathBasedBreadcrumbBuilder. I found that's broken on our site and actually decorate the core version with one that adds the route to the cache-ability of the path breadcrumb builder.

  • Status changed to Needs review 9 days ago
  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    No worries :) I'm not a native speaker either but I tend to want to get the grammar right, so I tend to look these things up when in doubt. You did make me think, though, and I believe the simple present is preferred here, as the implementation is arguably still to be written at the time of reading the documentation.

    Will change that little detail and leave at RTBC.

  • Status changed to RTBC 9 days ago
  • πŸ‡ΊπŸ‡ΈUnited States neclimdul Houston, TX

    left rtbc because this isn't a change this merge makes just something it highlights so could be a follow up.

  • πŸ‡§πŸ‡ͺBelgium kristiaanvandeneynde Antwerp, Belgium

    Should the manager just include that by default and this change would only be used for more exotic cases?

    It could, but just like you I'd argue that that is out of scope. For now I would focus on fixing the bugs caused by not correctly setting any cacheable metadata when the applies() check returns FALSE.

  • Pipeline finished with Success
    9 days ago
    Total: 507s
    #202121
  • πŸ‡§πŸ‡ͺBelgium BramDriesen Belgium πŸ‡§πŸ‡ͺ

    RE #54 now it reads better to my mind πŸ˜…

Production build 0.69.0 2024