[TYPO3-mvc] Caching problem?
Xavier Perseguers
xavier.perseguers at typo3.org
Tue Mar 22 14:34:28 CET 2011
Hello,
OK, I investigated the problem this morning (partly over Skype with
Bastian, thx).
Here is the result and there is a conceptual problem from my POV.
Just to freshen the ideas, I have a very basic plugin with 3 actions:
- index (listing of some records, each record is linked to the edit action)
- edit (edit form of a record)
- update (actual update of the record, when the edit form is submitted)
index action is cached, edit/update actions are not cached.
Basically, the Extbase dispatcher is responsible for converting a USER
plugin into a USER_INT if the action is configured to be non-cacheable.
This happens in the FE Request handler [1], in method handleRequest().
Whenever a call to isCacheable() returns FALSE, then the plugin is
transformed into a USER_INT and, as such, will be re-rendered each time
the page is generated.
Now, the problem I found is that this method was only invoked once,
after a TYPO3 cache clearing. The action tested for the isCacheable()
call was "index", as no parameter was provided and according to the
configuration, the index action should indeed be cached. So far so good.
The index action is rendered properly but for some reason, the edit
action was "never" called, nor was the "update" action. Well, in some
cases it was and I still don't understand why sometimes it works but I
now understand why it doesn't in most cases.
Default view (index) is:
http://domain.tld/test.html
The link to the edit action is:
http://domain.tld/test.html?tx_plugin_pi1[person]=1&tx_plugin_pi1[action]=edit&tx_plugin_pi1[controller]=Person
As the edit action is not cached, the link seems to look good (no cHash
which would make the action "cached") BUT the page is normally cached
(index action) and as such, as there is no cHash, TYPO3 serves the very
same page it has in cache, thus the index action!
I encountered this by debugging the handleRequest() method which happens
to be called only once, after a clear cache, meaning Extbase had no way
transforming the plugin into a USER_INT once it has been cached.
Bastian pointed out a part of the code where the generated cHash is
removed (or not) from URL, in the UriBuilder [2] in method uriFor(), at
the end, lines 470 to 474:
if ($actionName !== NULL
&& $this->useCacheHash === TRUE
&& !Tx_Extbase_Utility_Extension::isActionCacheable($extensionName,
$pluginName, $controllerArguments['controller'], $actionName)) {
$this->setUseCacheHash(FALSE);
}
After commenting out this whole block, my edit links are generated with
a cHash which forces TYPO3 to invoke Extbase again, thus the
handleRequest() method and then the plugin is properly invoked.
What happens: when generating 'edit' action links,
$actionName = 'edit';
$this->useCacheHash is TRUE and isActionCacheable() call returns FALSE
because 'edit' cannot be cached, OK but as the current action is cached,
the cHash which is used for cached actions is removed and TYPO3 does not
invoke handleRequest() anymore as it can be served from cache.
I don't really like having a cHash for a non-cached action but I don't
want either to have to go to Extbase dispatcher over and over again in
case the plugin is cached.
[1]
http://git.typo3.org/TYPO3v4/CoreProjects/MVC/extbase.git?a=blob;f=Classes/MVC/Web/FrontendRequestHandler.php;h=15eecced2855d76339fc0aa23643348b041a7211;hb=HEAD
[2]
http://git.typo3.org/TYPO3v4/CoreProjects/MVC/extbase.git?a=blob;f=Classes/MVC/Web/Routing/UriBuilder.php;h=38a2efcba7e1ebeb6b2e2e06fe61335a18b37eba;hb=HEAD
--
Xavier Perseguers
Release Manager TYPO3 4.6
TYPO3 .... inspiring people to share!
Get involved: http://typo3.org
More information about the TYPO3-project-typo3v4mvc
mailing list