During development of this blog I faced the problem that my homepage was getting slower and slower as I added more feeds to it. My first try was to just switch on caching for the action that calls the model methods to retrieve the feeds which worked very well for some time. But I recognized that I wanted to have different cache lifetimes for all the feeds. Caching the whole action wasn't good enough anymore.
So I did some search via Google and found an interesting part of "The Definite Guide to symfony" Book which talks about caching the Result of a Function Call.
Since I already had a static getFeed($feedName) method in my models to retrieve items of a feed it was easy to create a getCachedFeed($feedName) one which uses sfFunctionCache::call() method. But as I wanted everything to be configurable I also added a parameter to pass the cache object which now gives me the ability to configure the cache lifetime of every single feed aggregation. So the method now looks like getCachedFeed($feedName, $cacheInstance).
<?php //INSIDE THE ACTION $this->deliciousFeed = drFeedAggregator::getCachedFeed('Delicious', new sfFileCache(array( 'cache_dir' => sfConfig::get('app_feedAggregator_cacheDir'), 'lifetime' => sfConfig::get('app_homepage_delicious_lifetime') )) ); $this->googleReaderFeed = drFeedAggregator::getCachedFeed('GoogleReader', new sfFileCache(array( 'cache_dir' => sfConfig::get('app_feedAggregator_cacheDir'), 'lifetime' => sfConfig::get('app_homepage_googleReader_lifetime') )) );
You can also see in this code example that I followed best practise #24 from N1k0's talk at symfony Day Cologne 09. Now I can configurate the caching of the feeds on the homepage completely via app.yml.
This work by Dennis Benkert is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
© 2009 by Dennis Benkert - legal information
Yeah, very nice. And also now it's quite easy for you to test the getCachedFeed by passing different instances of sfFileCache through the nice decoupling and separation of concerns between the controller, the model and the caching strategy :-)
Exactly! I also moved the class name of the cache instance to app.yml. Now this is configurable, too. :)