The employer
Новичок
Стандартный обработчик кэширования в Smarty
Возможно, кому-то пригодится.
Как-то помог одному товарищу разобраться вот с каким вопросом:
> Есть ли в нем самом (или есть ли возможность приделать к нему) механизм блокировки, дабы предотвратить ситуации, когда второй запрос страницы приходит
> до завершения генерации кэша, и в итоге процесс выборки данных повторяется заново?
Есть штатная возможность приделать к нему собственный механизм кэширования, кторый может в том числе содержать реализацию блокировок.
Делается это при помощи Cache Handler Function: http://www.smarty.net/manual/en/section.template.cache.handler.func.php
Далее.
Можно сделать навеску над стандартным обработчиком.
Собственно, стандартный обработчик в виде целостной функции будет выглядеть так (кстати, не понимаю почему пацаны из смарти не сделали такой рефакторинг):
Теперь в этот обработчик ты можешь вставить (в ветки read и write) любую блокировку, какую захочешь.
> Правильно ли я понимаю, что достаточно вставить в ветку read что-то типа установки семафора, а в write, соответственно, его снятие?
Да.
> Годятся ли для этого функции?
> http://php.net/manual/en/ref.sem.php
Вполне годятся.
Возможно, кому-то пригодится.
Как-то помог одному товарищу разобраться вот с каким вопросом:
> Есть ли в нем самом (или есть ли возможность приделать к нему) механизм блокировки, дабы предотвратить ситуации, когда второй запрос страницы приходит
> до завершения генерации кэша, и в итоге процесс выборки данных повторяется заново?
Есть штатная возможность приделать к нему собственный механизм кэширования, кторый может в том числе содержать реализацию блокировок.
Делается это при помощи Cache Handler Function: http://www.smarty.net/manual/en/section.template.cache.handler.func.php
Далее.
Можно сделать навеску над стандартным обработчиком.
Собственно, стандартный обработчик в виде целостной функции будет выглядеть так (кстати, не понимаю почему пацаны из смарти не сделали такой рефакторинг):
PHP:
function standard_cache_handler(
$action
, &$smarty
, &$cache_content
, $tpl_file = null
, $cache_id = null
, $compile_id = null
, $exp_time = null
) {
switch( $action ) {
case "read":
$_auto_id = $smarty->_get_auto_id( $cache_id, $compile_id );
$_cache_file = $smarty->_get_auto_filename( $smarty->cache_dir, $tpl_file, $_auto_id );
$cache_content = $smarty->_read_file( $_cache_file );
return true;
case "write":
if( !@is_writable( $smarty->cache_dir ) ) {
// cache_dir not writable, see if it exists
if( !@is_dir( $smarty->cache_dir ) ) {
$smarty->trigger_error(
'the $cache_dir \'' . $smarty->cache_dir
. '\' does not exist, or is not a directory.', E_USER_ERROR
);
return false;
}
$smarty->trigger_error(
'unable to write to $cache_dir \'' . realpath($smarty->cache_dir)
. '\'. Be sure $cache_dir is writable by the web server user.', E_USER_ERROR
);
return false;
}
$_auto_id = $smarty->_get_auto_id( $cache_id, $compile_id );
$_cache_file = $smarty->_get_auto_filename( $smarty->cache_dir, $tpl_file, $_auto_id );
$_params = array( 'filename' => $_cache_file, 'contents' => $cache_content, 'create_dirs' => true );
require_once( SMARTY_CORE_DIR . 'core.write_file.php' );
smarty_core_write_file( $_params, $smarty );
return true;
case "clear":
$_auto_id = $smarty->_get_auto_id( $cache_id, $compile_id );
$_params = array(
'auto_base' => $smarty->cache_dir
, 'auto_source' => $tpl_file
, 'auto_id' => $_auto_id
, 'exp_time' => $exp_time
);
require_once( SMARTY_CORE_DIR . 'core.rm_auto.php' );
return smarty_core_rm_auto( $_params, $smarty );
default:
$smarty->_trigger_error_msg( "cache_handler: unknown action \"$action\"" );
return false;
}
}
> Правильно ли я понимаю, что достаточно вставить в ветку read что-то типа установки семафора, а в write, соответственно, его снятие?
Да.
> Годятся ли для этого функции?
> http://php.net/manual/en/ref.sem.php
Вполне годятся.