Problem/Motivation
In PHP 8.1 \Drupal\path_alias\AliasManager::cacheClear()
produces PHP deprecation notices because when it is called $this->cacheKey
is NULL and this is then passed to the cache system. See #3220021: [meta] Ensure compatibility of Drupal 9 with PHP 8.1 (as it evolves) for test evidence.
Steps to reproduce
Proposed resolution
The easy solution is to wrap $this->cache->delete($this->cacheKey);
with a check for $this->cacheKey being set. This, however, makes you realise that the cache flush is flawed. We're setting keys in \Drupal\path_alias\EventSubscriber\PathAliasSubscriber::onKernelController()
and the key is not related at all to the $source being passed into the cache flush.
At the moment we're using cache.data
as the backend so calling \Drupal\path_alias\AliasManager::cacheClear()
without a source probably should not flush all of that.
It turns out that the cache entry is for preloading and it does not matter if it is incorrect - it will fix it self over time. Therefore rather than trying to clear it we should leave it to expire and not try to clear it at all.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#6 | 3224592-6.patch | 3.05 KB | alexpott |
#6 | 5-6-interdiff.txt | 2.65 KB | alexpott |
Comments
Comment #2
alexpottComment #3
alexpottComment #5
alexpottHere's a fix for the test.
I'm not sure about this fix. After looking at the code and playing with it, given how the cache is used in conjunction with
$this->cacheKey
I think we’ll need a cache tag and to invalidate them on\Drupal\path_alias\AliasManager::cacheClear
if we want to do it properly. But I’m not convinced that that is worth it. We use the cache to preload multiple path aliases for a route - if we miss one path that appears on a page I’m not sure it matters. And we only cache for 24 hours so it will fix itself soon enough. I think maybe we should remove the cache deleting entirely and add a comment as to why it is not here.Comment #6
alexpottDiscussed with @catch. We agreed that calling
cache->delete()
here is not necessary as the is a preloading cache that improves performance but it does not matter if it is missing a path or has an extra path. Also since the preloading is an implementation detail of core's AliasManager I've not put this documentation on the interface.Comment #7
daffie CreditAttribution: daffie commentedThere is only one place in the alias manager where
$this->cache->get()
is used. Before this is called there is a test for$this->preloadedPathLookups === FALSE
. In the methodcacheClear()
does the follwing:$this->preloadedPathLookups = [];
. Therefor when one first calls the methodcacheClear()
, the code$this->cache->get()
will not be run. Therefor we can remove the call to$this->cache->delete($this->cacheKey)
in the methodcacheClear()
.@alexpott: The only problem that I have is that the name of the method
cacheClear()
gives to me the implicit expectation that the cache will be cleared, including$this->cache
. When the method is called with setting the parameter$source
, my implicit expectation would be that all caches for the alias manager would be deleted. If you do not agree with this, then I the patch in comment #6 is for me RTBC.The method is called from more places then only
\Drupal\path_alias\Entity\PathAlias::postSave
. The workspaces module does it inDrupal\workspaces\WorkspaceManager::doSwitchWorkspace
and the contrib modules fixed_path_alias and pathauto do the same. See: http://grep.xnddx.ru/search?text=-%3EcacheClear%28&filename=.Comment #8
alexpottRe #7 -
Given how the key changes, we cannot flush the cache unless we add a new cache tag to do this. However as this comment indicates, flushing the cache doesn't really change the outcome - the cache is used for preloading and miss or something not being in the cache, does not change the outcome. Imo we have this documented and everything is okay and tested. Also #6 documents that I discussed the operation of this with @catch who was one of the authors of the original code.
Comment #9
alexpottAlso if a path is provided we can't know all the cache entries that will have the path in because the cache key is determined by the request path. So even with a cache tag we'd either have to over zealously clear or not clear at all if $path is provided to this method.
Comment #10
daffie CreditAttribution: daffie commented@alexpott: Thank you for your explanation.
All the code changes look good to me.
The removal of the
$this->cache->delete()
is documented in the docblock of the method.For me it is RTBC.
Comment #11
alexpottFixing the title.
Comment #12
alexpottFixing issue summary.
Comment #13
mondrakeComment #15
catchCommitted/pushed to 9.3.x, thanks!
I wonder if we should open a follow-up to try to remove the cacheClear method and replace everything with cache tags, but seems optional.
Comment #16
andypost@catch filed #3226090: Deprecate \Drupal\path_alias\AliasManager::cacheClear() in favour of cachetags