Problem/Motivation
In a module, I'm trying to configure time based access restriction so I use a _custom_access callback in which I return an AccessResult object on which I apply setCacheMaxAge(60) to ensure that access is checked once per minute.
The problem is that this access check never expires for anonymous users - even if I set the page cache max age to 60 seconds too.
Logged in users do not have the same issue.
The same problem occurs with page content.
I created a quick gist to illustrate : https://gist.github.com/DuaelFr/7a11327b8a5acaa5da30
Steps to reproduce
- install Drupal standard
- create a tiny module like shown in the gist above
- navigate to /test as anonymous
- wait between 61 and 119 seconds
- reload the page
Expected result :
Something changed
Current result :
Nothing changed
Proposed resolution
No idea.
Remaining tasks
Find out what's going on. Fix it.
User interface changes
None.
API changes
None.
Data model changes
None.
Comments
Comment #2
duaelfrComment #3
catchThis is probably #2352009: Bubbling of elements' max-age to the page's headers and the page cache.
Comment #4
dawehnerWell yeah, this is basically by design sort of.
Comment #5
fabianx commentedThe workaround is to use:
- $attached['http_header']['Expires'] = time() + 60; (or a date format of it)
somewhere for _just_ this route.
While page cache does not use max-age header from a cacheable response, it does use the Expires header ...
Comment #6
duaelfr@Fabianx thank you very much for that workaround.
I think that's quite a big problem, though. Any site builder can create a view block with time based cache from the interface and put it on any page of hir site. S/he cannot imagine that this View is going to be cached for ever for anonymous users. Could the page cache module become aware of that max-age setting somehow?
Aside, while reading the page_cache code, in \Drupal\page_cache\StackMiddleware\PageCache::fetch() I've seen that if the Expire header was leasser or equal to the result of time(), cache was considered as permanent. I'd understand that an empty or negative Expire could be considered as permanent but an outdated one should just be considered as expired, isn't it? At least, we should rely on REQUEST_TIME instead of time().
Let's imagine I set my expire header as time() + 2s then there is a long rendering process before the response goes to page_cache fetch. At this given moment the expire value could already be outdated and considered as permanent. Weird, no?
Do you think I'm right? If I am, I'll open a new issue about that problem.
Comment #7
wim leersAgreed.
This is exactly what #2352009: Bubbling of elements' max-age to the page's headers and the page cache is about.