ModuleCache
Package | framework.modules |
---|---|
Inheritance | class ModuleCache » Module » LsObject |
Since | 1.0 |
Source Code | /framework/classes/modules/cache/Cache.class.php |
Пример использования:
// Получает пользователя по его логину public function GetUserByLogin($sLogin) { // Пытаемся получить значение из кеша if (false === ($oUser = $this->Cache_Get("user_login_{$sLogin}"))) { // Если значение из кеша получить не удалось, то обращаемся к базе данных $oUser = $this->oMapper->GetUserByLogin($sLogin); // Записываем значение в кеш $this->Cache_Set($oUser, "user_login_{$sLogin}", array(), 60*60*24*5); } return $oUser; } // Обновляет пользовател в БД public function UpdateUser($oUser) { // Удаляем кеш конкретного пользователя $this->Cache_Delete("user_login_{$oUser->getLogin()}"); // Удалем кеш со списком всех пользователей $this->Cache_Clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG,array('user_update')); // Обновлем пользовател в базе данных return $this->oMapper->UpdateUser($oUser); } // Получает список всех пользователей public function GetUsers() { // Пытаемся получить значение из кеша if (false === ($aUserList = $this->Cache_Get("users"))) { // Если значение из кеша получить не удалось, то обращаемся к базе данных $aUserList = $this->oMapper->GetUsers(); // Записываем значение в кеш $this->Cache_Set($aUserList, "users", array('user_update'), 60*60*24*5); } return $aUserList; }
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
_aBehaviors | Список поведений в виде готовых объектов, формируется автоматически | LsObject | |
aBehaviors | array | Список поведений | LsObject |
aCacheBackends | array | Список бекендов кеширования | ModuleCache |
aStats | array | Статистика кеширования | ModuleCache |
bAllowForce | bool | Возможность принудительно использовать кешировоание, даже если оно отключено в конфиге | ModuleCache |
bAllowUse | bool | Разрешать или нет кеширование | ModuleCache |
bIsInit | bool | Указывает на то, была ли проведенна инициализация модуля | Module |
sCacheType | string|null | Дефолтный тип кеширования | ModuleCache |
sPrefixSmartCache | string | Префикс для "умного" кеширования | ModuleCache |
Public Methods
Method | Description | Defined By |
---|---|---|
AddBehaviorHook() | Добавляет хук поведения | LsObject |
AttachBehavior() | Присоединяет поведение к объекту | LsObject |
CalcStats() | Подсчет статистики использования кеша | ModuleCache |
Clean() | Чистит кеши | ModuleCache |
ClearOldCache() | Удаляет старый кеш в случайном порядке | ModuleCache |
Delete() | Удаляет значение из кеша по ключу(имени) | ModuleCache |
DetachBehavior() | Отсоединяет поведение от объекта | LsObject |
Get() | Получить значение из кеша | ModuleCache |
GetBehavior() | Возвращает объект поведения по его имени | LsObject |
GetBehaviors() | Возвращает все объекты поведения | LsObject |
GetLife() | Получает значение из текущего кеша сессии | ModuleCache |
GetStats() | Возвращает статистику использования кеша | ModuleCache |
Init() | Инициализация | ModuleCache |
InitParams() | Инициализация необходимых параметров модуля | ModuleCache |
RemoveBehaviorHook() | Удаляет хук поведения | LsObject |
RunBehaviorHook() | Запускает хук поведения на выполнение | LsObject |
Set() | Записать значение в кеш | ModuleCache |
SetInit() | Помечает модуль как инициализированный | Module |
SetLife() | Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry | ModuleCache |
Shutdown() | Метод срабатывает при завершении работы ядра | Module |
SmartGet() | Получения значения из "умного" кеша для борьбы с конкурирующими запросами | ModuleCache |
SmartSet() | Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами | ModuleCache |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля | LsObject |
__clone() | Блокируем копирование/клонирование объекта | Module |
__construct() | Конструктор, запускается автоматически при создании объекта | LsObject |
__get() | Обработка доступа к объекты поведения | LsObject |
isInit() | Возвращает значение флага инициализации модуля | Module |
Protected Methods
Method | Description | Defined By |
---|---|---|
GetCacheBackend() | Возвращает объект бекенда кеша | ModuleCache |
HashName() | Формирует хеш от имени ключа кеша | ModuleCache |
MultiGet() | Поддержка мульти-запросов к кешу | ModuleCache |
PrepareBehaviors() | Инициализация поведений | LsObject |
Property Details
Список бекендов кеширования
Статистика кеширования
Возможность принудительно использовать кешировоание, даже если оно отключено в конфиге
Разрешать или нет кеширование
Дефолтный тип кеширования
Префикс для "умного" кеширования
Method Details
public void CalcStats(int $iTime, string $sMethod)
| ||
$iTime | int | Время выполнения метода |
$sMethod | string | имя метода |
public function CalcStats($iTime, $sMethod)
{
$this->aStats['time'] += $iTime;
$this->aStats['count']++;
if ($sMethod == 'Dklab_Cache_Backend_Profiler::load') {
$this->aStats['count_get']++;
}
if ($sMethod == 'Dklab_Cache_Backend_Profiler::save') {
$this->aStats['count_set']++;
}
}
Подсчет статистики использования кеша
public bool Clean(string $cMode='all', array $aTags=array (
), string|null $sCacheType=NULL, bool $bForce=false)
| ||
$cMode | string | Режим очистки кеша |
$aTags | array | Список тегов, актуально для режима Zend_Cache::CLEANING_MODE_MATCHING_TAG |
$sCacheType | string|null | Тип кеша |
$bForce | bool | Принудительно использовать кеширование, даже если оно отключено в конфиге |
{return} | bool |
public function Clean($cMode = Zend_Cache::CLEANING_MODE_ALL, $aTags = array(), $sCacheType = null, $bForce = false)
{
if (!$this->bAllowUse and !($this->bAllowForce and $bForce)) {
return false;
}
if (!is_array($aTags)) {
$aTags = array($aTags);
}
/**
* Переводим теги с нижний регистр
*/
$aTags = array_map('strtolower', $aTags);
$oCacheBackend = $this->GetCacheBackend($sCacheType);
return $oCacheBackend->Clean($cMode, $aTags);
}
Чистит кеши
public void ClearOldCache()
|
public function ClearOldCache()
{
$this->Clean(Zend_Cache::CLEANING_MODE_OLD);
}
Удаляет старый кеш в случайном порядке Рекомендуется запускать раз в пару дней из под крона
public bool Delete(string $sName, string|null $sCacheType=NULL, bool $bForce=false)
| ||
$sName | string | |
$sCacheType | string|null | |
$bForce | bool | |
{return} | bool |
public function Delete($sName, $sCacheType = null, $bForce = false)
{
if (!$this->bAllowUse and !($this->bAllowForce and $bForce)) {
return false;
}
/**
* Удаляем данные их кеша
*/
$oCacheBackend = $this->GetCacheBackend($sCacheType);
return $oCacheBackend->Delete($this->HashName($sName));
}
Удаляет значение из кеша по ключу(имени)
public mixed|bool Get(string|array $sName, string|null $sCacheType=NULL, bool $bForce=false, bool $bKeepInMemory=false)
| ||
$sName | string|array | Имя ключа |
$sCacheType | string|null | Тип кеша |
$bForce | bool | Принудительно использовать кеширование, даже если оно отключено в конфиге |
$bKeepInMemory | bool | Если true, то данные дополнительно будут сохранены в памяти на время выполнения запроса (скрипта). В результате чего повторные Get() запросы к кешу будут значительно быстрее. Параметр не поддерживает мульти-запросы к кешу. Данные параметр следует использовать очень осторожно, т.к. кешированные данные нельзя будет обновить/удалить до конца выполнения запроса. |
{return} | mixed|bool |
public function Get($sName, $sCacheType = null, $bForce = false, $bKeepInMemory = false)
{
if (!$this->bAllowUse and !($this->bAllowForce and $bForce)) {
return false;
}
/**
* Запрос сразу на несколько ключей?
*/
if (is_array($sName)) {
return $this->MultiGet($sName, $sCacheType);
}
/**
* При необходимости смотрим в памяти
*/
if ($bKeepInMemory) {
$sKeyMemory = 'auto_keep_in_memory_' . $sName;
if (false !== ($mData = $this->GetLife($sKeyMemory))) {
return $mData;
}
}
$oCacheBackend = $this->GetCacheBackend($sCacheType);
$mData = $oCacheBackend->Get($this->HashName($sName));
/**
* Сохраняем в памяти
*/
if ($bKeepInMemory and $mData !== false) {
$this->SetLife($mData, $sKeyMemory);
}
return $mData;
}
Получить значение из кеша
protected ModuleCache_EntityBackend GetCacheBackend(string|null $sCacheType=NULL)
| ||
$sCacheType | string|null | Тип кеша |
{return} | ModuleCache_EntityBackend | Объект бекенда кеша |
protected function GetCacheBackend($sCacheType = null)
{
if ($sCacheType) {
$sCacheType = strtolower($sCacheType);
} else {
$sCacheType = $this->sCacheType;
}
/**
* Устанавливает алиас memory == memcached
*/
if ($sCacheType == 'memory') {
$sCacheType = 'memcached';
}
if (isset($this->aCacheBackends[$sCacheType])) {
return $this->aCacheBackends[$sCacheType];
}
$sCacheTypeCam = func_camelize($sCacheType);
/**
* Формируем имя класса бекенда
*/
$sClass = "ModuleCache_EntityBackend{$sCacheTypeCam}";
$sClass = Engine::GetEntityClass($sClass);
if (class_exists($sClass)) {
/**
* Создаем объект и проверяем доступность его использования
*/
$oBackend = new $sClass;
if (true === ($mResult = $oBackend->IsAvailable())) {
$oBackend->Init(array('stats_callback' => array($this, 'CalcStats')));
$this->aCacheBackends[$sCacheType] = $oBackend;
return $oBackend;
} else {
throw new Exception("Cache '{$sCacheTypeCam}' not available: {$mResult}");
}
}
throw new Exception("Not found class for cache type: " . $sCacheTypeCam);
}
Возвращает объект бекенда кеша
public mixed GetLife(string $sName)
| ||
$sName | string | Имя ключа |
{return} | mixed |
public function GetLife($sName)
{
return $this->Get($sName, 'life', true);
}
Получает значение из текущего кеша сессии
public array GetStats()
| ||
{return} | array |
public function GetStats()
{
return $this->aStats;
}
Возвращает статистику использования кеша
protected string HashName(string $sName)
| ||
$sName | string | Имя ключа кеша |
{return} | string |
protected function HashName($sName)
{
return md5(Config::Get('sys.cache.prefix') . $sName);
}
Формирует хеш от имени ключа кеша
public void Init()
|
public function Init()
{
$this->InitParams();
}
Инициализация
public void InitParams()
|
public function InitParams()
{
$this->bAllowUse = (bool)Config::Get('sys.cache.use');
if (is_bool(Config::Get('sys.cache.force'))) {
$this->bAllowForce = Config::Get('sys.cache.force');
}
$this->sCacheType = strtolower(Config::Get('sys.cache.type'));
}
Инициализация необходимых параметров модуля
protected bool|array MultiGet(array $aName, string|null $sCacheType=NULL)
| ||
$aName | array | Имя ключа |
$sCacheType | string|null | Тип кеша |
{return} | bool|array |
protected function MultiGet($aName, $sCacheType = null)
{
if (!count($aName)) {
return false;
}
$oCacheBackend = $this->GetCacheBackend($sCacheType);
if ($oCacheBackend->IsAllowMultiGet()) {
$aKeys = array();
$aKv = array();
foreach ($aName as $sName) {
$sHash = $this->HashName($sName);
$aKeys[] = $sHash;
$aKv[$sHash] = $sName;
}
$data = $oCacheBackend->Get($aKeys);
if ($data and is_array($data)) {
$aData = array();
foreach ($data as $key => $value) {
$aData[$aKv[$key]] = $value;
}
if (count($aData) > 0) {
return $aData;
}
}
return false;
} else {
$aData = array();
foreach ($aName as $sName) {
if ((false !== ($data = $oCacheBackend->Get($this->HashName($sName))))) {
$aData[$sName] = $data;
}
}
if (count($aData) > 0) {
return $aData;
}
return false;
}
}
Поддержка мульти-запросов к кешу Такие запросы поддерживает только memcached, поэтому для остальных типов делаем эмуляцию
public bool Set(mixed $mData, string $sName, array|string $aTags=array (
), int|bool $iTimeLife=false, string|null $sCacheType=NULL, bool $bForce=false)
| ||
$mData | mixed | Данные для хранения в кеше |
$sName | string | Имя ключа |
$aTags | array|string | Список тегов, для возможности удалять сразу несколько кешей по тегу |
$iTimeLife | int|bool | Время жизни кеша в секундах |
$sCacheType | string|null | Тип кеша |
$bForce | bool | Принудительно использовать кеширование, даже если оно отключено в конфиге |
{return} | bool |
public function Set($mData, $sName, $aTags = array(), $iTimeLife = false, $sCacheType = null, $bForce = false)
{
if (!$this->bAllowUse and !($this->bAllowForce and $bForce)) {
return false;
}
if (!is_array($aTags)) {
$aTags = array($aTags);
}
/**
* Переводим теги с нижний регистр
*/
$aTags = array_map('strtolower', $aTags);
/**
* Сохраняем данные в кеш
*/
$oCacheBackend = $this->GetCacheBackend($sCacheType);
return $oCacheBackend->Set($mData, $this->HashName($sName), $aTags, $iTimeLife);
}
Записать значение в кеш
public void SetLife(mixed $mData, string $sName)
| ||
$mData | mixed | Данные для сохранения в кеше |
$sName | string | Имя ключа |
public function SetLife($mData, $sName)
{
$this->Set($mData, $sName, array(), false, 'life', true);
}
Сохраняет значение в кеше на время исполнения скрипта(сессии), некий аналог Registry
public bool|mixed SmartGet(string $sName, string|null $sCacheType=NULL, bool $bForce=false)
| ||
$sName | string | Имя ключа |
$sCacheType | string|null | Тип кеша |
$bForce | bool | Принудительно использовать кеширование, даже если оно отключено в конфиге |
{return} | bool|mixed |
public function SmartGet($sName, $sCacheType = null, $bForce = false)
{
if (!$this->bAllowUse and !($this->bAllowForce and $bForce)) {
return false;
}
/**
* Если данных в основном кеше нет, то перекладываем их из временного
*/
if (($data = $this->Get($sName, $sCacheType, $bForce)) === false) {
$this->Set($this->Get($this->sPrefixSmartCache . $sName, $sCacheType, $bForce), $sName, array(), 60,
$sCacheType, $bForce); // храним данные из временного в основном не долго
}
return $data;
}
Получения значения из "умного" кеша для борьбы с конкурирующими запросами Если кеш "протух", и за ним обращаются много запросов, то только первый запрос вернет FALSE, остальные будут получать чуть устаревшие данные из временного кеша, пока их не обновит первый запрос Текущая реализация имеет недостаток - размер кеша увеличивается в два раза
public bool SmartSet(mixed $data, string $sName, array $aTags=array (
), int|bool $iTimeLife=false, string|null $sCacheType=NULL, bool $bForce=false)
| ||
$data | mixed | Данные для хранения в кеше |
$sName | string | Имя ключа |
$aTags | array | Список тегов, для возможности удалять сразу несколько кешей по тегу |
$iTimeLife | int|bool | Время жизни кеша в секундах |
$sCacheType | string|null | Тип кеша |
$bForce | bool | Принудительно использовать кеширование, даже если оно отключено в конфиге |
{return} | bool |
public function SmartSet($data, $sName, $aTags = array(), $iTimeLife = false, $sCacheType = null, $bForce = false)
{
$this->Set($data, $this->sPrefixSmartCache . $sName, array(), $iTimeLife !== false ? $iTimeLife + 60 : false,
$sCacheType, $bForce);
return $this->Set($data, $sName, $aTags, $iTimeLife, $sCacheType, $bForce);
}
Устанавливаем значение в "умном" кеша для борьбы с конкурирующими запросами Дополнительно сохраняет значение во временном кеше на чуть большее время