Problem/Motivation

#2245767: Allow blocks to be configured to show/hide on 200/403/404 response pages added a status mode block visibility condition with the url cache context, but it only varies by the status code so I think we could use that instead.

Steps to reproduce

Proposed resolution

Add an exception status code cache context, and use this in the block visibility condition.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3516173

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

catch created an issue. See original summary.

catch’s picture

Status: Active » Needs review
catch’s picture

Component: block.module » system.module

The actual condition plugin lives in system module.

alexpott’s picture

How does this work? Doesn't this need to be something we can determine from the request? Which we can't do for the response code isn't this going to end up in the page cache too?

catch’s picture

When we get a 404 or 403, HttpExceptionSubscriberBase sets the exception on the request.

By the time we reach the rendering of the 404 or 403 page, this is available, so the cache context will work.

It won't do anything if someone has a response subscriber that adds a 418 or 201 status code or weird things like that, those would all count as 200.

We could rename it to ExceptionStatusCodeCacheContext and then when there is no exception status code, return '0' instead of '200'. This would match how the visibility condition works a lot closer. Did that in a new commit.

There's no bubbling of cache contexts to the page cache and won't be (we might bubble max age at some point, there's an issue) because it only ever caches by URL.

alexpott’s picture

I've tested this solution with easy breadcrumb as described by #3516169: Adding url.path to breadcrumb cache context results in every 404 page getting a different dynamic page cache entry and it works fantastically. This is a fantastic change which will improve the cacheability of any block that is using the response status condition.

catch’s picture

Just in case anyone lands here due to large cache tables, while this should fix the dynamic page cache, it's very easy to end up with a large internal page cache database too.

One reason is #3011426: Page cache size is unlimited when arbitrary query parameters are requested for query strings.

For 404s/403s the page cache supports much shorter TTLs, which means 404/403 pages can be expired on cron or set to not cache at all. This was added in #2699613: Set a shorter TTL for 404 responses in page_cache module.

smustgrave’s picture

Status: Needs review » Needs work

Not sure the right status but with the new service won't we need a CR?

Even though a task does this kind of change need test coverage?

alexpott’s picture

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

catch’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs tests, -Needs change record

Added a unit test and a change record.

catch’s picture

Neither standard nor umami use the response for the breadcrumbs block, so we can't add this into an existing performance test without some extra work. However I think we could have a follow-up to use the visibility, and we should then be able to see a performance improvement for 404 pages vs both HEAD and the MR here.

I could potentially add the performance test here without taking advantage of the changes, which we could then show the difference in the follow-up issue - will see what people think first though.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

Ran the test-only job https://git.drupalcode.org/issue/drupal-3516173/-/jobs/9300338 to show the coverage.
I did rebase so I could re-run random failures.

Believe all feedback for this one has been addressed

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new667 bytes

The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

catch’s picture

Status: Needs work » Reviewed & tested by the community

Rebased.

godotislate made their first commit to this issue’s fork.

godotislate’s picture

Neither standard nor umami use the response for the breadcrumbs block, so we can't add this into an existing performance test without some extra work. However I think we could have a follow-up to use the visibility, and we should then be able to see a performance improvement for 404 pages vs both HEAD and the MR here.

Maybe we can add and do the follow up to use the visibility first, with the performance test, then come back here to see the difference?

godotislate’s picture

Status: Reviewed & tested by the community » Needs review

One small nit/question on the MR, can self-RTBC. Though maybe as I suggested we block this on the updating either standard/umami to add the condition to the breadcrumbs with performance test first.

godotislate’s picture

Added a follow up from an MR comment about deprecating getLabel(): #3589614: Deprecate CacheContextInterface::getLabel() and CacheContextsManager::getLabels()

catch’s picture

OK new issue with test is here: #3589683: Add a performance test for 404 pages.

Assuming the pipeline comes back green (passes locally but you never know), I'll cherry-pick the two commits over here so we then get a diff on the performance test (hopefully).

I had to allow the breadcrumb block to show on the front page, since excluding on the front page is also per-path (although it could potentially use the is_front cache context - could be another follow-up from this issue to try to make that work). But the breadcrumbs don't actually render on the front page so no visual difference.

catch’s picture

So the test works but because Umami has other blocks with page visibility conditions, dynamic page cache still ends up with the url.path cache context, which means this issue doesn't affect the test. If Umami was using layout builder for the front page and maybe node pages it would probably help.

Might try the same thing with standard performance test instead..

catch’s picture

OK I merged in the tests from the other issue for now.

The commit that shows the difference vs. the behaviour in HEAD is https://git.drupalcode.org/project/drupal/-/merge_requests/11672/diffs?c...

Given I had to jump through a couple of hoops to get performance tests to show the problem, I think we could consider doing the following:

1. Merge this without performance test coverage.

2. Merge the test coverage issue, but without the tweaks to Olivero block config that demonstrate the problem here. They'd still pick up something else.

3. Try to fix #3589822: Try to reduce cache context granularity from path conditions which should then show a difference in Umami.

godotislate’s picture

I think the performance test shows that it's worth getting this in sooner rather than later, so I'm good with merging this now without test coverage first. RTBC +1 for that.

catch’s picture

Status: Needs review » Reviewed & tested by the community

OK I removed the test changes from the MR again. Given this was RTBC before apart from the one applied suggestion, going ahead and moving back to RTBC.

Note that there is test coverage here already, it's not just a full integration test. The performance tests do show that just because it works in isolation it doesn't necessarily improve things on real sites though - although it should if they don't use path visibility otherwise.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

I think the instanceof check suggested in the MR comments in a good idea. One question I have is what to do if the there is an exception but it fails the instanceof check - what should we return then? 500?

catch’s picture

Status: Needs work » Reviewed & tested by the community

I missed that comment in the various test excitement, added the instanceof check.

One question I have is what to do if the there is an exception but it fails the instanceof check - what should we return then? 500?

It already falls back to '0' if there's no exception status code, which I think is all we can do here. If we're rendering blocks when an exception is passed in here, and that exception isn't an http exception... I'm just not sure how that could happen at all tbh.

alexpott’s picture

Version: main » 11.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed c2bcef504f7 to main and ce37b0619b5 to 11.x. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

  • alexpott committed c2bcef50 on main
    task: #3516173 Block status code visibility condition should use a...

  • alexpott committed ce37b061 on 11.x
    task: #3516173 Block status code visibility condition should use a...
wim leers’s picture