«Если рендер вернул пустую строку — что-то сломалось, в кэш не кладём». Звучит как разумная защита. На деле это правило дважды загоняло прогрев в тупик.
Это шестая часть цикла «Кэш фрагментов и Redis».
Пустое бывает законным
- вторая страница сетки, если товаров на одну страницу;
- блок допов у товара, у которого допов нет;
- SEO-текст категории, который ещё не написали.
Всё это — правильный результат рендера. Пустой, но правильный.
Тупик со сторожем полноты
Правило «пустое не кэшируем» плюс сторож полноты (восьмая часть) дают замкнутый круг. Сторож видит, что ячейки нет, ставит её в очередь. Воркер рендерит, получает пусто, не кладёт. Сторож снова видит, что ячейки нет…
В одном случае в таком круге залипли 2092 из 3118 ячеек — две трети очереди состояли из законно пустых блоков, которые рендерились снова и снова.
В другой раз с тем же правилом очередь за шесть прогонов сократилась с 996 до 963 — то есть почти стояла. После исправления — 305 рендеров за прогон, ноль ошибок.
Как отличить сбой
Признак сбоя — исключение при рендере, а не пустой результат. Пустая строка кладётся в кэш, как любая другая. Ошибка ловится и в кэш не попадает.
try {
$out = frag_render_isolated($render, $args);
} catch (Throwable $e) {
error_log("frag render failed {$type}: " . $e->getMessage());
frag_count('errors');
return null; // сбой — в кэш не кладём
}
frag_store_set($key, $out); // пустая разметка — тоже результат
Если шаблон глотает ошибки и возвращает пусто — это повод починить шаблон, а не ввести правило про пустоту.
Прогрев крутится, а очередь не уменьшается?
Пришлите адрес — проверю, не застряли ли в ней законно пустые блоки.
// загружаю комментарии…