Bug #70079
closed
Performance impact of 6.2.15 class loader cache emptying
Added by Christian Weiske about 9 years ago.
Updated almost 8 years ago.
Description
Issue #67246 modified the way the class loader works:
Whenever a unresolvable class is detected, the class loading cache is thrown away.
We have two situations which make this undesirable:
- Code that uses a custom class autoloader. Each class in our code that is not resolvable via the default TYPO3 autoloader makes the class loading cache be thrown away. This increased page loading time by 1500% for us. We could work around this by putting our own autoloader before the TYPO3 autoloader.
- Extbase and FluidTYPO3 try to guess class names, and often guess it wrong with their first try. This also throws away the class loader cache, still slowing down our code - it increases page loading time 6.2.14 to 6.2.15 by 40%.
The following fluidtypo3 and extbase methods are responsible for this:
FluidTYPO3\Flux\Provider\AbstractProvider->resolveFormClassName()
FluidTYPO3\Flux\Utility\ResolveUtility::buildControllerClassNameFromExtensionKeyAndControllerType()
FluidTYPO3\Flux\Utility\ResolveUtility::resolveFluxControllerClassNameByExtensionKeyAndAction()
TYPO3\CMS\Extbase\Mvc\Controller\ActionController->resolveViewObjectName()
TYPO3\CMS\Extbase\Mvc\Request->getControllerActionName()
The TYPO3 team should really reconsider the idea of always assuming that the class loader cache is broken, just because a class could not be found.
Even if this supposedly only happens in development context, it's still a major nuisance during development.
I do get the problem, but how can we tell whether the class cache is seriously broken or an extension guess wrong?
TBH I don't really get how a concatenated string can be wrong "at first"? Which entity changes that string on reload?
Can you point me to "cache is thrown away"?
Generally your class loaded should of course always work before the Core's.
Markus Klein wrote:
Can you point me to "cache is thrown away"?
It is not. But still the ext_autoload.php from every extension are indeed read on every request for any not found class. I can imagine the performance impact here in Development context where this is done every time because the information that the class loader did not find the class is not cached.
- Status changed from New to Needs Feedback
Christian Weiske wrote:
The TYPO3 team should really reconsider the idea of always assuming that the class loader cache is broken, just because a class could not be found.
The thing we merged is a hack. A bad one. That is why I blocked this change for a long time. But it also solves an issue we have on production systems.
You have two options to work around it:
- Do not use Development context for development. There are very few things TYPO3 does differently for this context and any of them you can achieve differently, so this is a good option with few changes to make.
- Switch to composer class loading. This is possible with 6.2 as well, gives you a huge performance boost and solves a lot of issues (including the one in question here). You can even throw away custom class loaders (in case they do not provide any magic)
We as TYPO3 maintainers have 2 options:
- Revert that change, ignore the potential production system impact and stick more closely to our patch level policy (to not break stuff)
- Keep the change and educate people to not use Development context in TYPO3 6.2 (or use composer class loading)
Mathias Schreiber wrote:
TBH I don't really get how a concatenated string can be wrong "at first"? Which entity changes that string on reload?
They have a list of potential class names and check each of them if it exists. See $possibleViewName
in extbase/Mvc/Controller/ActionController.php::resolveViewObjectName()
Markus Klein wrote:
Can you point me to "cache is thrown away"?
Core_ClassLoader::buildClassLoadingInformation() . As Helmut said, it's not really thrown away but reloaded from all extensions with an autoload registry a.k.a. ext_autoload.php
.
Markus Klein wrote:
Generally your class loaded should of course always work before the Core's.
Why should it? It has always been working nice the way it is. Also, the TYPO3 class loader should be used first because the majority of classes used are TYPO3 classes. Performance would suffer if our class loader would always be used first, only to find that it is not able to load TYPO3 core classes.
Why should it? It has always been working nice the way it is. Also, the TYPO3 class loader should be used first because the majority of classes used are TYPO3 classes. Performance would suffer if our class loader would always be used first, only to find that it is not able to load TYPO3 core classes.
Ok that for sure depends a bit what you do in your class loader. I, probably falsely, assumed that this is a very fast and optimized code that just does some array lookup or the like.
Regarding the "thrown away", I'm sorry to be picky about that phrasing, but it is a huge difference between "just loading some very few ext_autoload" files and repopulating the complete autoload cache!
Generally I would be really glad to remove this hacky thing again, if we could figure out where those spurious hick-ups with missing class loading information comes from. But we failed to reproduce this issue reliably and hence couldn't make a fix that solves the root cause. Therefore we decided to better have working Production instances than fast Dev-Instances. It's been a trade-off.
Markus Klein wrote:
But we failed to reproduce this issue reliably and hence couldn't make a fix that solves the root cause
We had same/similar issues.
Mostly caused by eID calls or backend AJAX while cache is empty produced invalid class loader cache because PATH_tslib was not defined but used in ext_autoload - but i cannot remember exact circumstances.
One solution is to increase class loader cache TTL to such an high value it will never reach end of life. I do not know any valid reason having a TTL on class loader cache.
BTW. this (the performance impact of 6.2.15 class loader) is not only a problem for DEV, but for PRODUCTION too, every time you need to clear the autoload cache you risk an immense high load on your FE machines - not a problem for small to medium sized sites - but for enterprise sized sites.
- Status changed from Needs Feedback to Under Review
- Assignee set to Alexander Opitz
- Target version set to 6.2.18
Changed the functionality of the implemented fallback in #67246
- Let this reload of cache only happen on production as dev builds normally do not have such high traffic.
- Rebuild the cache on first occurrence, so all open threads will have something from this information and not only the next complete started thread.
Unfortunately i am currently not able to reproduce this classes cache bug in 6.2.17, even if i delay the time between building the autoload classes cache and further execution of the code.
So i am not sure if this bug is fixed somehow in the latest version, or if it is now somehow more seldom than in versions before 6.2.15.
- Target version changed from 6.2.18 to Candidate for patchlevel
- Status changed from Under Review to Closed
Dropped for 6.2 since that branch is in priority bugfix mode
Also available in: Atom
PDF