[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