Изменения

Перейти к: навигация, поиск

HMVC

6109 байтов добавлено, 10:09, 18 мая 2016
м
Нет описания правки
Об одном правильном подходе к HMVC (Hierarchical MVC)и кэшированию HTML на стороне сервераДелим страницу на блоки, каждый блок обрабатывается одним контроллером. При этом контроллеры образуются в "иерархию" - каждый блок может вызывать другие и подставлять внутрь себя их вывод. Каждый вызов контроллера описывается именем контроллера и параметрами, в которых, аналогично URL-параметрам, допускаются только сериализованные данные, а не объекты. Для корректной инвалидации кэша используем теги. Далее запуск каждого контроллера делится на два метода:* check() - запускается всегда, перед попыткой загрузить результат из кэша. Здесь должны выполняться следующие задачи:** обработка запросов на модификацию данных (и редирект после сохранения изменений)** валидация параметров запроса, редиректы на очищенные URL** вычисление ключа кэша** если хочется, вызов будущих подзапросов (метод subrequest()). это бывает полезно, если не хочется множить ключи кэша в зависимости от набора подзапросов. в то же время, это бывает вредно, если для вызова подзапросов нужно совершить дополнительную работу, которая при этом будет так или иначе совершена в run().** также можно вычислить и теги для будущего вывода, хотя практического смысла это не имеет* run() - запускается, только если результат не удалось загрузить из кэша. run() делает следующее:** вычисляет вывод (HTML)** вычисляет теги кэша для вывода (если только check() это уже не сделал)** запускает подзапросы (если только их, опять-таки, не запускал check()) Частый кейс: вкрапления ссылок "править" или других мелких зависящих от пользователя элементов (например, цен товаров в валюте пользователя). Варианты решения:* добавить ID пользователя в ключ кэша - нам не подходит, пользователей ведь будет много, только кэш забьётся лишним мусором* вынести подстановку этих элементов на javascript, в браузер - вменяемое решение, но генерирует много дополнительных запросов и замедляет полную загрузку страницы* наше решение: отдельный небольшой дочерний контроллер, в который через параметры передаются готовые данные для определения, выводить или не выводить ссылку (например, набор пользователей, которым разрешено править выведенный элемент). Эти параметры будут кэшированы вместе с основным выводом в наборе подзапросов, таким образом, после загрузки HTML из кэша можно будет проверить эти разрешения "малой кровью" и вывести (или не выводить) ссылки. Порядок обработки запроса:# Создать главный контроллер# Создать контроллер layout'а (почти ничем не отличается от обычного, кроме того, что является как бы "подзапросом" главного, но при этом не подставляется в его вывод, а оборачивает его вывод)# Начиная с главного контроллера:## Вызываем check()## Пробуем загрузить вывод из кэша## Если вывод загрузился и актуален, и если check() не вызывал subrequest() — загружаем записи о подзапросах из вывода, загруженного из кэша## Если не загрузился:### Если check() вычислил теги для будущего ключа кэша - НЕ сбрасываем их!### Вызываем run()### Сохраняем вывод, теги и (если подзапросы вызывались в run()) записи о подзапросах в кэш## Делаем (3) со всеми контроллерами подзапросов## Подставляем выводы подзапросов в вывод их родительских контроллеров# Делаем (3) с контроллером layout'а# Вычисляем Last-Modified из тегов кэша всех контроллеров (время модификации тега обновляется при каждом его сбросе)# Сравниваем Last-Modified с запрошенным If-Modified-Since и отправляем HTTP 304, если кэш браузера актуален# Отправляем вывод обычным образом
== English ==

Навигация