Кейс таков. У нас есть метод, который формирует ассоциативный массив из символьных кодов и id инфоблоков.
В каких случаях нам нужно обновлять кэш в папке /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");
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");