Have Your Magento Caches Update Themselves

Magento has a lot of caches. They are (in my opinion) the biggest reason Magento is usable as a platform (If you think Magento runs slowly now – turn them off for a little bit).

One thing that I as a programmer find odd is that the caches in Magento are intelligent enough to flag themselves as invalidated, however they generally require that they be refreshed by hand. This can be especially irritating when you are running Magento Enterprise Edition and your full page cache is constantly being invalidated due to product and category updates.

In order to improve our site performance I wanted to find a practical way to run with the full page cache on all the time without requiring me to babysit it 24 hours a day. I figured I had to find the code that was triggered when you told the admin panel to update the cache.

It turns out that like most things in Magento, unless you know how it works, it is not immediately obvious where this code is located. One tool I have found invaluable is Commerce Bug by Alan Storm. This tool told me that the cache admin page is controller by the controller that is located at:

/app/code/core/Mage/Adminhtml/controllers/CacheController.php

Now in this controller you will find a number of actions. The one that is going to help us is massRefreshAction(). Inside you will see that there is code that actually refreshes the cache

$tags = Mage::app()->getCacheInstance()->cleanType($type);

This is close but not quite what we need yet. The $type is a string code for the cache. We don’t want to always refresh the cache. Just the ones that have been flagged as invalidated.

Looking deeper into the ->getCacheInstance() class that is returned shows us an interesting function that is available called ->getInvalidatedTypes(). BINGO! That is exactly what we are looking for.

Looking at what this function returns we find an array of objects that contain the codes of caches that have been invalidated. Now all we have to do is iterate through this list and refresh those caches.

The final script will look like the following:

$types = Mage::app()->getCacheInstance()->getInvalidatedTypes();
foreach($types as $type) {
     Mage::app()->getCacheInstance()->cleanType($type->getId());
}

Now that we have a script that is refreshing the caches, we just need this script to run every so often and it will refresh any caches as required. I set it to run every 2 minutes, but your mileage may vary.

Leave a Reply

Your email address will not be published. Required fields are marked *