1. Главная
  2. Блоги
  3. Блог Ильич Рамирес Санчес

Кеширование на файлах. Новая версия. Более тормозно но более гибко

Главные вкладки

Берем 5ый друпал. Zend_Framework - кладем его в подкаталог library.
В $conf путь к ZF определяется так.
'filecache_zend_path' => 'library' . PATH_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov',

От ZF на самом деле надо очень мало - следующие файлы и каталоги:
Cache, Cache.php, Exception.php, Loader, Loader.php, Version.php

В комментариях описаны примерные конфигурационные параметры.
По умолчанию пользуется стандартный зендовский класс Zend_Cache_Backend_File.
У меня есть своя его версия чуть получше - чистка мусора в ней проводится раз в 5000 раз или как задашь и актуальность записей оценивается по своему.

По результатам тестирования - на 30% медленнее предыдущей модели. НО. Тут больше гибкости - учитывая заморочки 6го друпала - я буду развивать именно этот вариант Smile

Вот такие пироги Smile

Гибкость в следующем -можно подставлять бекенды кеша какие нравятся. Для APC, для мемкеша и тд.

Потом может разовью решение в сторону того что будет похоже на cacherouter. Вот такие дела. Smile

/*
*
* Filecache2 by Ilya V. "brainstorm" Azarov, brainstorm.name
* This module uses Zend framework cache to organize file cachig for drupal
*
* $conf configuration variables in settings.php
* $conf['filecache_zend_path'] - library path of zend framework
* by default 'library' . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov'
* $conf['filecache_maincacheclass'] = 'Zend_Cache_Backend_File' - main class for caching
* we use our class - Zend_Cache_Backend_Fastfile for caching
* Other advanced options would be later
* See _filecache2_params for defaults
*/

/*
* Wrapper for cache $conf parameters
*/

function _filecache2_params($param){
static $defaults;
if(!isset ($defaults) ) $defaults = array (
'filecache_zend_path' => 'library' . PATH_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'Azarov',
'filecache_maincacheclass' => 'File', // Zend_Cache_Backend_File
'filecache_path' => 'files/cache',
'filecache_opts_Zend_Cache_Backend_File' => array (
'cache_dir' => null,
'file_locking' => true,
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755
),
// Zend_Cache_Backend_Fastfile
'filecache_opts_Fastfile' => array (
'cache_dir' => false, // say system - we need this option but it's auto
'file_locking' => true,
'cleaning_factor' => '5000', // evertime on couter is equal - make full clean
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755,
'file_name_prefix' => 'zc',
),
// Zend_Cache_Backend_File
'filecache_opts_File' => array (
'cache_dir' => false, // say system - we need this option but it's auto
'file_locking' => true,
'hashed_directory_level' => 3,
'hashed_directory_umask' => 0755,
'file_name_prefix' => 'zc',
)
);
global $conf;
if(isset ($conf[$param] ) ) return $conf[$param];
elseif(isset ($defaults[$param] ) ) return $defaults[$param];
return false;
}
function _filecache2_init_loaders(){
static $loaded;
if(!isset ($loaded) ){
set_include_path (get_include_path () . PATH_SEPARATOR . _filecache2_params('filecache_zend_path') );
include_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
$loaded = true;
}
}
function _filecache2_name_encode($cid){
return str_replace ('=', '_', base64_encode ($cid) );
}
function _filecache2_get_cache_object($table){
static $objects;
if(isset ($objects[$table] ) ) return $objects[$table];
_filecache2_init_loaders();
// FOR FUTURE - make objects depending on per table configuration
$dirname = _filecache2_params('filecache_path') . DIRECTORY_SEPARATOR . $table;
if(!is_dir ($dirname) ) mkdir ($dirname, 0755, true);
$bopts = _filecache2_params('filecache_opts_' . _filecache2_params('filecache_maincacheclass') );
if(!$bopts) Zend_Cache::throwException('No options for ' . _filecache2_params('filecache_maincacheclass') );
if(isset ($bopts['cache_dir'] ) ) $bopts['cache_dir'] = $dirname;
$cache = Zend_Cache::factory('Core', _filecache2_params('filecache_maincacheclass'),
array ('caching' => true, 'lifetime' => null, 'automatic_cleaning_factor' => 0, 'ignore_user_abort' => true),
$bopts
);
$objects[$table] = $cache;
return $objects[$table];
}
function cache_get ($cid, $table = 'cache') {
global $user;
// Garbage collection necessary when enforcing a minimum cache lifetime
$cache_flush = variable_get ('cache_flush', 0);
if ($cache_flush && ($cache_flush + variable_get ('cache_lifetime', 0) <= time ())) {
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_OLD);
variable_set ('cache_flush', 0);
}
$mcid = _filecache2_name_encode($cid);
if($co = [user=unserialize ]unserialize [/user](_filecache2_get_cache_object($table)->load($mcid) ) ){
return $co;
}
return 0;
}
function cache_set ($cid, $table = 'cache', $data, $expire = CACHE_PERMANENT, $headers = NULL) {
// save($data, $id = null, $tags = array(), $specificLifetime = false)
$mcid = _filecache2_name_encode($cid);
$t = time ();
$specificLifetime = false;
if($expire != CACHE_PERMANENT ){
$t = $expire - $t;
if($t > 0) $specificLifetime = $t;
}
$o = new stdClass();
$o->data = $data;
$o->created = time ();
$o->expire = $expire;
$o->headers = $headers;
$s = serialize ($o);unset ($o);
_filecache2_get_cache_object($table)->save($s, $mcid, array (), $specificLifetime);
}
function cache_clear_all ($cid = NULL, $table = NULL, $wildcard = FALSE){
global $user;
if (!isset ($cid) && !isset ($table)) {
cache_clear_all (NULL, 'cache_page');
return;
}
if (empty ($cid)) {
if (variable_get ('cache_lifetime', 0)) {
// We store the time in the current user's $user->cache variable which
// will be saved into the sessions table by sess_write(). We then
// simulate that the cache was flushed for this user by not returning
// cached data that was cached before the timestamp.
$user->cache = time ();
$cache_flush = variable_get ('cache_flush', 0);
if ($cache_flush == 0) {
// This is the first request to clear the cache, start a timer.
variable_set ('cache_flush', time ());
}
else if (time () > ($cache_flush + variable_get ('cache_lifetime', 0))) {
// Clear the cache for everyone, cache_flush_delay seconds have
// passed since the first request to clear the cache.
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_OLD);
variable_set ('cache_flush', 0);
}
}else{
// No minimum cache lifetime, flush all temporary cache entries now.
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_ALL);
}
}else{
if ($wildcard) {
_filecache2_get_cache_object($table)->clean(Zend_Cache::CLEANING_MODE_ALL);
}else{
$mcid = _filecache2_name_encode($cid);
_filecache2_get_cache_object($table)->remove($mcid);
}
}
}

Комментарии

Аватар пользователя Ильич Рамирес Санчес Ильич Рамирес Санчес 6 июля 2008 в 16:30

CACHE_TEMPORARY - обычно складываются в отдельные таблицы и функция та же что и у CACHE_PERMANENT, так что в данной конфигурации модуль для 5ки достаточен Smile
Для 6ки в процессе - и там уже думать сильно надо на тему очисток кеша меню и форм... дело ближайших двух недель...

Логотип drupal.ru

Содержимое сайта публикуется на условиях CreativeCommons Attribution-ShareAlike 3.0 или более поздней версии. Программные коды в тексте статей — на условиях GNU GPL v2 или более поздней версии.

Документация по совместной работе с репозиторием drupal.ru – https://docs.drupal.ru/code

Drupal – торговая марка Дриса Бёйтарта

12+

AltStyle によって変換されたページ (->オリジナル) /