Кейс таков. У нас есть метод, который формирует ассоциативный массив из символьных кодов и id инфоблоков.
public static function getIBlocksCodeIDMap()
{
if (!\Bitrix\Main\Loader::includeModule('iblock'))
return;
$arIBlocksIDsByCode = array();
$cache = new CPHPCache();
$cache_time = 86400;
$cache_id = 'getIBlocksCodeIDMap' . SITE_ID;
$cache_path = '/getIBlocksCodeIDMap/';
if ($cache_time > 0 && $cache->InitCache($cache_time, $cache_id, $cache_path))
{
$res = $cache->GetVars();
if (is_array($res["IBlocksCodeIDMap"]) && (count($res["IBlocksCodeIDMap"]) > 0))
$arIBlocksCodeIDMap = $res["IBlocksCodeIDMap"];
}
if (empty($arIBlocksCodeIDMap))
{
$rsIBlocks = \CIBlock::GetList(
Array(),
Array(
"SITE_ID" => SITE_ID
)
);
global $CACHE_MANAGER;
$CACHE_MANAGER->StartTagCache($cache_path);
while ($arIBlock = $rsIBlocks->Fetch()) {
$CACHE_MANAGER->RegisterTag("iblock_id_".$arIBlock["ID"]);
$arIBlocksCodeIDMap[$arIBlock['CODE']] = $arIBlock['ID'];
}
$CACHE_MANAGER->RegisterTag("getIBlocksCodeIDMap");
$CACHE_MANAGER->RegisterTag("iblock_id_new");
$CACHE_MANAGER->RegisterTag("getIBlocksCodeIDMap");
$CACHE_MANAGER->EndTagCache();
if ($cache_time > 0) {
$cache->StartDataCache($cache_time, $cache_id, $cache_path);
$cache->EndDataCache(array("IBlocksCodeIDMap" => $arIBlocksCodeIDMap));
}
}
return $arIBlocksCodeIDMap;
} |
|
В каких случаях нам нужно обновлять кэш в папке /getIBlocksCodeIDMap/ ?
1 - при добавлении инфоблока. Произведётся сброс по тэгу iblock_id_new в методе CIBlock::Add
2 - изменение символьного кода инфоблока (ну т.е. обновление инфоблока) и удаление инфоблока. Произведётся сброс по тэгу iblock_id_ в методах CIBlock::Delete и CIBlock::Update.
Т.е. всё хорошо, у нас всегда актуальные данные. Но есть один ньюанс:
Сброс по тэгу iblock_id_ будет производиться и при обновлении/удалении/добавлении элемента/секции этого инфоблока (CIBlockSection, CIBlockElement). Т.е. наш кэш будет сбрасываться вообще по каждому чиху, связанному с хотя бы одним из инфоблоков. Хотя нам, в данное методе, абсолютно не нужно реагировать на какие-бы то ни было изменения в элементах или секциях инфоблоков. Нас интересуют только само наличие инфоблоков и их символьные коды.
Получается избыточность.
Почему бы штатным методам не добавить более узкоспециализированные и сброс кэша по ним.
Т.е. , например , в методе CIBlockElement::Update добавить ClearByTag("CIBlockElement") и ClearByTag("CIBlockElement_Update"), при этом оставив на месте ClearByTag("iblock_id_" . .... ).
И когда разработчик пишет свой метод, то он может более гибко управлять сбросом кэша с результатами работы своего метода. Т.е. если нужно, например, реагировать только на изменения в элементах, в метод добавляется $CACHE_MANAGER->RegisterTag("CIBlockElement"); и всё.
Или, в случае моего примера:
$CACHE_MANAGER->RegisterTag("CIBlock_Update");
$CACHE_MANAGER->RegisterTag("CIBlock_Add");