User:Barre/MediaWiki/Extensions

From KitwarePublic
< User:Barre‎ | MediaWiki
Revision as of 18:46, 14 March 2005 by Barre (talk | contribs) (add stuff about the cache problem)
Jump to navigationJump to search

Cache Problem

As of MediaWiki 1.3 and 1.4, the extension feature is limited by the caching mechanism. If your extension is used to display dynamic contents and therefore needs to be re-executed each time the page is accessed, you will notice pretty early on that it does not work as expected. The problem is that MediaWiki caches the contents of the page the first time it is rendered, and serves that cached output until the corresponding page is modified again. Several parameters are considered when the decision is made to use the cached output instead of re-rendering the page, and most of them deal with comparing the creation time of the cache against the creation time of the page (cur_timestamp/cur_touched is the SQL database). If the cache is older than the page, it is re-rendered.

The code below uses that knowledge to 'touch' the page and invalidate its cache. It is indeed slightly identical to the code in the Title::invalidateCache() method. Sadly invalidateCache() can not be used in an extension: even though it sets cur_touched to 'now', at the time we would be calling this method we would still be in the process of creating and rendering the page itself and the page would be cached anyway once we would be done with our extension. At the end of the day the cache would always end up newer than cur_touched, defeating the whole purpose of calling invalidateCache(). The trick here is to set cur_touched in the future, something not too intrusive, say 'now' + 120 seconds, provided that we expect the whole page (and our extension code) to be executed and rendered within 120 seconds. That way, cur_touched remains 'fresher' than the cache, and the next time the page is accessed, the cache creation time will appear to be older than cur_touched, forcing the page to be re-rendered, and forcing cur_touched to be, again, set in the future and appear fresher than the new cache, etc.

 $ts = mktime();
 $now = gmdate("YmdHis", $ts + 120);
 $ns = $wgTitle->getNamespace();
 $ti = wfStrencode($wgTitle->getDBkey());
 $sql = "UPDATE cur SET cur_touched='$now' WHERE cur_namespace=$ns AND cur_title='$ti'";
 wfQuery($sql, DB_WRITE, "");