Using the cache component

Dynamic pages often create a huge amount of load and require more time to render the result that will be displayed to the user. However there is not the need to create the same data again and again - you can cache it and therefore save time and resources. Stubbles contains a cache component that can be used to cache data in various ways.

Simple example

<?php
// in bootstrap code:
$cacheStrategy  = new stubDefaultCacheStrategy();
$cacheContainer = new stubFileCacheContainer('rss-feeds');
$cacheContainer->setStrategy($cacheStrategy);
stubCache::addContainer($cacheContainer);
...
// later on in your application
$cache = stubCache::factory('rss-feeds');
if ($cache->has('exampleId') == true) {
    $content = $cache->get('exampleId');
} else {
    $content = generateContent();
    $cache->put('exampleId', $content);
}
echo $content;
?>

As you can see it is really simple to use the cache: just get a cache container with the id from the factory, then check if the cache knows what we want to display. If yes retrieve the data from cache, else generate it and put it into the cache.

Configuring the cache

It is possible to get rid of the bootstrap code and configure the cache via xml:

<?xml version="1.0" encoding="iso-8859-1"?>
<xj:configuration
    xmlns:xj="http://xjconf.net/XJConf"
    xmlns:cfg="http://stubbles.net/util/XJConf"
    xmlns="http://stubbles.net/util/cache">
  <cache>
    <fileContainer id="rss-feeds">
      <cacheDirectory>/path/to/cache_directory</cacheDirectory>
      <defaultStrategy ttl="86400" maxSize="-1" gcProbability="1" />
    </fileContainer>
  </cache>
</xj:configuration>

Here the cache is configured with a container that stores the cache data in files within the directory /path/to/cache_directory. Additionally the container is configured with a strategy that has a time to live (ttl) of one day which means that the cache contents are valid for one day until they will be considered as expired. The maximum size of the cache is set to infinite. Setting it to a positive number this will denote the amount of bytes that the cache will use at maximum. The last option is the probability of a garbage collection run. Here this probability is one percent. If you set this to 0 the garabage collection will never be done which means that expired cache data will never be removed, while a setting of 100 means that the garabage collection will be run always.

(Side note: the garbage collection will be triggered every time when you use the net::stubbles::util::cache::stubCache::factory() method.)

You may create your own configuration style by implementing the net::stubbles::util::cache::stubCacheInitializer interface.

Create your own caching strategy

A caching strategy makes the decisions for the cache container. While the cache container only knows how to save and retrieve the cached data, the strategy knows when data should be cached or not or when data should be considered as expired.

To create your own caching strategy you just need to implement the net::stubbles::util::cache::stubCacheStrategy interface.

  • isCachable() should decide whether an item can be cached. This may be done by checking the size of the cache and of the item to cache and deciding whether the item fits into the cache or not.
  • isExpired() decides whether a cached item should be considered as expired or not.
  • shouldRunGc() decides whether a run of the garbage collection should be done or not. Possible things to consider may be the amount of items in the cache, the space used by the cache or any other condition you may consider useful.

See net::stubbles::util::cache::stubDefaultCacheStrategy for an example implementation.

Create your own cache container

A cache container does the real work of storing, retrieving and removing the cache data. Stubbles contains a net::stubbles::util::cache::stubFileCacheContainer which stores the cache data in files on the disc. (We may add more containers as we have the need for them and/or find them useful.)

To create your own cache container you need to implement the net::stubbles::util::cache::stubCacheContainer interface. To make this simple you may extend the net::stubbles::util::cache::stubAbstractCacheContainer which already contains all stuff that deals with the strategy and defines various abstract methods which ease the development of an own cache container because the own container just needs to deal with the storing, retrieving and removing operations and not with the strategy as well.