Thingy Ma Jig is the blog of Nicholas Thompson and contains any useful tips, sites and general blog-stuff which are considered interesting or handy!
Posted on 24 February 2010 in
tips
programming
performance
How to
Drupal
I run XCache on the server that powers this site. XCache is cool. Out of the box, it allows caching of PHP compile code in memory, after all once a file is compile you shouldn't keep needing to compile it on every page load, should you?
There is another feature XCache has which not many people know about or use; Variable Caching. When you configure your XCache (the ini file is usually found in /etc/php.d/xcache.ini), you should see some options in there for allocating memory for variables as well as code (see var_size). This is essentially a persistent place to put stuff which can be called back out on the next page load.
Another handy thing which I'd never seen before (and I've been using Drupal for around 4 years), is the page_cache_fastpath() function. This is not implemented by default, but if you take a look in _drupal_bootstrap, there is a stage called DRUPAL_BOOTSTRAP_EARLY_PAGE_CACHE. I'd never noticed this before.
In both Drupal 5 and Drupal 6, this stage will check if the page_cache_fastpath
variable is set to TRUE and, if so, will call a the page_cache_fastpath() function. This function can then echo out a page and return TRUE which causes Drupal to exit there and then. This all happens BEFORE Drupal connects to the database.
So I set myself a little challenge… and then Googled for it to find that it's pretty much been done before, although it seemed to require Memcache. I also found that CacheRouter could do this too but thought it was a little excessive for me needs, plus I still wanted a challenge!
It turns out to be pretty easy.
$conf = array( 'cache_inc' => './sites/example.com/cache.inc', );
define('XCACHE_PREFIX', 'mysite_');
cache_set
:
if ($table == 'cache_page') { cache_get($cid, $table); }
This will, for cache_page entries only, insert the data and headers into XCache as an array.
return $cache
part:
if ($table == 'cache_page') { // If we're here and on cache_page, looks like the xcache wasn't present... lets chuck it in there for next time. $xcache_expire = $cache->expire > 0 ? $cache->expire - time() : NULL; $ret = xcache_set(XCACHE_PREFIX . $table . ':'. $cid, array('data' => $cache->data, 'headers' => $cache->headers), $cache->expire); }
xcache_unset_by_prefix
function (for some odd reason). Under the cache_clear_all(NULL, 'cache_page');
line near the beginning of cache_clear_all
, add the following:
xcache_unset_by_prefix(XCACHE_PREFIX .'cache_page');