Сегодня столкнулся со странной хреновиной, которую вдруг мне бросил memcache, а именно, ошибку «Invalid Memcache->connection member variable» при попытке взять/установить любые данные в кэш.
Ситуация:
Использую Yii, пытаюсь закешировать запрос к базе с зависимостью (dependency) по тэгу (код под спойлером ниже). При первом запросе всё проходит хорошо — данные из базы вынимаются, кэш записывается, тэги устанавливаются. Но при повторном запросе, вылезает та самая ошибка. После полной очистки кэша, всё заново — первый запрос проходит отлично, потом опять ошибка.
Код:
Свернутый текст
Класс зависимости:
<?php
/**
* Зависимость кэша от тэгов
*/
class CTagsCacheDependency extends CCacheDependency {
/**
* @var array|null массив тэгов
*/
private $_tags = null;
/**
* Создает зависимость по тэгам
* @param array|Tag $tags тэг(и)
*/
public function __construct($tags) {
if(is_array($tags))
$this->_tags = $tags;
else
$this->_tags[0] = $tags;
}
/**
* Выбирает из кэша данные по тэгам и создает отсутствующие
* @return array|void timestamp`ы тэгов
* @throws CException
*/
public function generateDependentData() {
if($this->_tags === null)
throw new CException(Yii::t('3d', 'Тэги кэша не заданы.'));
$tags = array();
foreach($this->_tags as $tag) {
$tagTime = $tag->getTag();
if($tagTime === false) {
$tagTime = Time::getMicrotime();
$tag->setTag();
}
$tags[] = $tagTime;
}
return $tags;
}
/**
* @return array|null все тэги зависимости
*/
public function getTags() {
return $this->_tags;
}
}
А вот абстракция тэга:
<?php
/**
* Абстракция тэга кэша.
*/
abstract class Tag {
/**
* string префикс тэгов в кэше
*/
const PREFIX = 'tag_';
/**
* @var int время жизни тэга
*/
private $_lifeTime;
/**
* @var string имя тэга (без префикса)
*/
private $_name;
/**
* @var ICache объект кэша
*/
private $_cache;
/**
* @param $name имя тэга
* @param int $lifeTime время жизни в кэше.
* @param string|ICache $cache название или объект кэша
*/
public function __construct($name, $lifeTime = 11111, $cache = 'cache') {
$this->_name = $name;
$this->_lifeTime = $lifeTime;
if($cache instanceof ICache) {
$this->_cache = $cache;
} else {
$this->_cache = Yii::app()->getComponent($cache);
}
}
/**
* Обнолвяет тэг в кэше
*/
public function setTag() {
$this->_cache->set($this->buildRealName(), Time::getMicrotime(), $this->_lifeTime);
Yii::trace(Yii::t('3d', 'Установлен тэг [{tag}].', array('{tag}' => $this->_name)), '3d.cache.Tag');
}
/**
* @return int значение тэга в кэше
*/
public function getTag() {
$tag = $this->_cache->get($this->buildRealName());
Yii::trace(Yii::t('3d', 'Из кэша взят тэг [{tag}].', array('{tag}' => $this->_name)), '3d.cache.Tag');
return $tag;
}
/**
* Удаляет тэг из кэша
*/
public function deleteTag() {
$this->_cache->delete($this->buildRealName());
Yii::trace(Yii::t('3d', 'Из кэша удален тэг [{tag}].', array('{tag}' => $this->_name)), '3d.cache.Tag');
}
/**
* @return string имя тэга
*/
public function getName() {
return $this->_name;
}
/**
* @return string имя тэга в кэше
*/
public function buildRealName() {
return self::PREFIX . $this->_name;
}
}
Кто-нибудь сталкивался с подобным? Гугл на запрос с текстом ошибки ничего определенного не дал.
_____________
Блог | VK | GitHub | Twitch