Consolidating Cache Management in Zend Framework


In version 1.10, Zend added an Application Resource to the Zend Framework for easily setting up your Caching resources through configuration files.

1 resources.cachemanager.cacheCoreFile.frontend.name = "Core"
2 resources.cachemanager.cacheCoreFile.frontend.options.lifetime = 3600
3 resources.cachemanager.cacheCoreFile.frontend.options.cache_id_prefix = APPLICATION_ENV "_cache_core_file"
4 resources.cachemanager.cacheCoreFile.frontend.options.automatic_serialization = true
5 resources.cachemanager.cacheCoreFile.frontend.options.automatic_cleaning_factor = 1
6 resources.cachemanager.cacheCoreFile.backend.name = "File"
7 resources.cachemanager.cacheCoreFile.backend.options.cache_dir = APPLICATION_PATH "/data/cache"

The problem is that components like Doctrine, Zend_Translate, Zend_Db and so on all have directives for their own cache configurations.

This makes managing cache times, invalidations, and timeouts very difficult.

A solution to this is to use the cachemanger to create your cache then pass that cache onto your other components through the bootstrap ( see example below ).

01 class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
02 ...
03 $this->_cache = null;
04 protected function _initCache() {
05 $this->bootstrap('cachemanager');
06 $cache = $this->getResource('cachemanager')
07 ->getCache('cacheCoreFile');
08 $this->_cache = $cache;
09 Zend_Registry::set('cacheCoreFile', $cache);
10 }
11
12 protected function _initTranslateCache() {
13 $this->bootstrap('cache');
14 $this->bootstrap('translate');
15 Zend_Translate::setCache($this->_cache);
16 }
17
18 protected function _initDoctrineCache() {
19 $this->bootstrap('cache');
20 $this->bootstrap('doctrine');
21 $doctrineAdapter = new DoctrineAdapter(
22 $this->_cache
23 , 'my_doctrine_cache_prefix'
24 );
25 $manager = Doctrine_Manager::getInstance()
26 $manager->setAttribute(
27 Doctrine_Core::ATTR_RESULT_CACHE
28 , $doctrineAdapter
29 );
30 }
31 ...
32 }

Most of the Zend components are pretty straight forward in that they accept an instance of Zend_Cache. Doctrine on the other hand defines it’s own cache drivers. Thanks to Benjamin Steininger we have a Doctrin_Cache driver implementation for Zend_Cache.

I made a small modification to the “save” method to add some custom cache tags, which I’ll explain in a minute.

01 class DoctrineAdapter implements Doctrine_Cache_Interface {
02 ...
03 public function save($id, $data, $lifetime = false) {
04 $id = $this->_prefix . $id;
05 return $this->_cache->save(
06 $data
07 , $id
08 , array(
09 My_CacheTags::TAG_DOCTRINE
10 )
11 , $lifetime
12 );
13 }
14 ...
15 }

Zend_Cache tags allow for “categorizing” of cached items.

To make my tag management easier I created a class with all the tags I use as static properties. This also allows me to reflect on the class for building my cache admin interfaces.

1 class My_CacheTags {
2 const TAG_MODULE_DEFAULT = "TAG_MODULE_DEFAULT";
3 const TAG_MODULE_OTHER = "TAG_MODULE_OTHER";
4 const TAG_ACTION = "TAG_ACTION";
5 const TAG_VIEW = "TAG_VIEW";
6 const TAG_DOCTRINE = "TAG_DOCTRINE";
7 // Zend Translate automatically adds it's tag Zend_Translate so we'll use it's tag name
8 const TAG_TRANSLATE = "Zend_Translate";
9 }

Now, emptying specific groups of items from the cache is much easier since we can specify which tags I want to clean from the cache.

1 $cache->clean(
2 Zend_Cache::CLEANING_MODE_MATCHING_TAG,
3 array(
4 My_CacheTags::TAG_MODULE_DEFAULT
5 , My_CacheTags::TAG_VIEW
6 )
7 );

The set-up described gives me much better insite as to how my application is configured, allows for easier changes and managing my cache is much simpler.

From bryanhughes.name

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s