Caching in Yii with tags
Yii allows you to cache data in the form of an array returned directly from the database.
And the caching system has different dependencies. But none of these dependencies allows you to automatically track changes in a table without accessing it (I mean CDbCacheDependency), which is pointless in loaded systems.
For such things came up with the so-called tagging. Those. some kind of tag is created, which is saved with all the caches associated with this table. And as soon as it changes, all related caches should reboot. As it turned out in Yii, this is done very simply.
It is worth mentioning that for greater comfort Active Record is used.
It is done like this. Create a new dependency and save it, for example, in components:
In the model, we indicate when we will use the new dependency. Since we want to do this for the entire model, add the code to the beforeFind function :
Well, or wherever we want, the main thing here is "$ this-> cache (30, new CTagCacheDependency (get_class ($ this)));"
As a tag, we simply have the name of the class, the model associated with a particular table.
Well, when we delete or save something, we write in the right places (in the afterDelete, afterSave functions):
Thereby we update the tag associated with this model, and accordingly with the table. Now, when the tag is updated as a result of updating the table, all caches with dependency on this tag will need to be updated.
The default cache is used - component: cache. But you can specify your other.
Used Books:
UPD Important!
Updated the code of the CTagCacheDependency class .
Now the constructor accepts the Component name as a string. For instance:
Made due to incorrect work with memcache.
And the caching system has different dependencies. But none of these dependencies allows you to automatically track changes in a table without accessing it (I mean CDbCacheDependency), which is pointless in loaded systems.
For such things came up with the so-called tagging. Those. some kind of tag is created, which is saved with all the caches associated with this table. And as soon as it changes, all related caches should reboot. As it turned out in Yii, this is done very simply.
It is worth mentioning that for greater comfort Active Record is used.
It is done like this. Create a new dependency and save it, for example, in components:
/**
* CTagCacheDependency class.
*
* CTagCacheDependency represents a dependency based on a autoincrement(timestamp) of tags
*
* @author Roman
* @since 1.0
*/
class CTagCacheDependency extends CCacheDependency
{
/**
* @var autoincrement(timestamp) param is used to
* check if the dependency has been changed.
*/
public $tag;
/**
* Cache component, by default used - cache
* @var CCache
*/
public $cache;
/**
* Name of cache component, by default used - cache
* @var string
*/
public $cacheName;
/**
* Constructor.
* @param string $tag value of the tag for module
*/
public function __construct($tag=null, $cacheName='cache')
{
$this->tag=$tag;
$this->cacheName = $cacheName;
}
/**
* Generates the data needed to determine if dependency has been changed.
* This method returns the integer(timestamp).
* @return mixed the data needed to determine if dependency has been changed.
*/
protected function generateDependentData()
{
if($this->tag!==null)
{
$this->cache = Yii::app()->getComponent($this->cacheName);
$t = $this->cache->get($this->tag);
if ($t === false) {
$t = microtime(true);
$this->cache->set($this->tag, $t);
}
return $t;
}
}
}
In the model, we indicate when we will use the new dependency. Since we want to do this for the entire model, add the code to the beforeFind function :
protected function beforeFind() {
$this->cache(30, new CTagCacheDependency(get_class($this)));
parent::beforeFind();
}
Well, or wherever we want, the main thing here is "$ this-> cache (30, new CTagCacheDependency (get_class ($ this)));"
- 30 - cache storage time, but it is better to put this value in a variable
- CTagCacheDependency - the class of our new dependency
- get_class ($ this) - tag name - model name
As a tag, we simply have the name of the class, the model associated with a particular table.
Well, when we delete or save something, we write in the right places (in the afterDelete, afterSave functions):
Yii::app()->cache->set(get_class($this), microtime(true), 0);
- 0 - infinite storage
- get_class ($ this) - tag name - model name
- microtime (true) - new tag value
Thereby we update the tag associated with this model, and accordingly with the table. Now, when the tag is updated as a result of updating the table, all caches with dependency on this tag will need to be updated.
The default cache is used - component: cache. But you can specify your other.
Used Books:
UPD Important!
Updated the code of the CTagCacheDependency class .
Now the constructor accepts the Component name as a string. For instance:
$this->cache($duration, new CTagCacheDependency(get_class($this), 'cache'));
Made due to incorrect work with memcache.