Question

TL;DR

Can/should cache tags in Magento be dynamic?

Background

I'm creating a CMS integration from an external CMS into Magento. The data is stored in Elasticsearch in AWS. I have a custom controller which the page's URL is rewritten to, which uses the URL as a key and loads the data from a custom block I created called content/dynamic.

Now I want to add block caching to it.

I know that the pertinent settings here are the cache tags and the cache key.

I'm thinking of using Mage_Cms_Model_Block::CACHE_TAG as well as the store as base cache tags, then adding a custom cache tag e.g. Me_Content_Model_Dynamic::CACHE_TAG, and the appropriate <global><cache><types> entry for that so that I can clear all cached dynamic content from the Cache Management screen in Magento admin.

One of the features I need to implement is to be able to refresh content caches for the content/dynamic block for a specific CMS page, as well as any content blocks underneath it.

Specifics

I'm thinking of adding another cache tag that is dynamic, e.g. dynamic_content_hashofURLhere to each page's instance of content/dynamic and all child blocks of it, so that I can easily identify dynamic page's cache entries for all content relating to a certain page.

Question

Is this the right way to use the cache tags?

It seems to me to be an easy way to target and invalidate a whole page worth of block cache entries for a page (no matter how many there are) without having to construct the cache key for each content block in the page and invalidate them individually.

Are dynamic cache tags used in the Magento code base already?

Is this best practice?

For clarity - I don't want to be able to clear any of the dynamic cache tags from the Cache Management page. I'd want to do this programatically. From the Cache Management page I'd only target a static cache tag that I add separately from this dynamic one.

Was it helpful?

Solution

Can/should cache tags in Magento be dynamic?...Is this the right way to use the cache tags?

Yes! This is exactly what cache tags are for - to group a number of cache entries together.

Here are some quotes from various blogs:

Cache tags exist so that we can selectively clear cache instances.

Source: Erfan Emani

The $data stored in the cache can also be tagged with metadata. This allows for logical groupings of cache entries for mass deletion.

Source: Nick Jones


Presumably having dynamic cache tags would mean that you could end up with hundreds or thousands of cache tags in your cache storage. Whether or not this introduces a performance impact over not having those cache tags would probably require some benchmarking, however in theory it should not introduce a large overhead as the cache tags are not queried unless being cleared for deletion.

Assuming the dynamic cache tag ended up as dynamic_content_HISUDFHS8y92333 you could easily clear all content block cache entries for the page HISUDFHS8y92333 like this:

/** @var Mage_Core_Model_Cache $cache */
$cache = Mage::app()->getCacheInstance();
$cache->clean(array(Me_Content_Model_Dynamic::CACHE_TAG . '_HISUDFHS8y92333'));

Are dynamic cache tags used in the Magento code base already?

Yes.

For a quick example you can take a look at Mage_Core_Block_Abstract::addModelTags():

# File: app/code/core/Mage/Core/Block/Abstract.php
public function addModelTags(Mage_Core_Model_Abstract $model)
{
    $cacheTags = $model->getCacheIdTags();
    if (false !== $cacheTags) {
        $this->addCacheTag($cacheTags);
    }
    return $this;
}

If you examine Mage_Core_Model_Abstract::getCacheIdTags you will see that it returns an array of the existing model's cache tags with the model's ID appended to the end:

# File: app/code/core/Mage/Core/Model/Abstract.php
public function getCacheIdTags()
{
    $tags = false;
    if ($this->getId() && $this->_cacheTag) {
        $tags = array();
        if (is_array($this->_cacheTag)) {
            foreach ($this->_cacheTag as $_tag) {
                $tags[] = $_tag.'_'.$this->getId();
            }
        } else {
            $tags[] = $this->_cacheTag.'_'.$this->getId();
        }
    }
    return $tags;
}

This method gets called by Mage_Core_Model_Abstract::getCacheTags, which means that dynamic cache tags are used in any Magento model (that extends from core model abstract) which is cache enabled.

Is this best practice?

Yeah, sure. It's much better than searching the cache storage for keys that match a certain pattern just to delete them all.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top