Основы кэширования
Введение
Невозможно создать высокопроизводительный фреймворк без надлежащего кэширования. CppCMS предоставляет комплексное API кэширования, позволяющее сохранять кэш согласованным и обновленным.
В этом уроке демонстрируется первый и простой уровень в кэшировании - кэширование, основанное на тайм-ауте.
Для примера, мы вычислим факториал и сохраним полученные значения в кэше.
Данные
Наша форма ввода будет содержать только два поля: arg
и submit
.
struct input_form : public cppcms::form { cppcms::widgets::numeric<int> arg; cppcms::widgets::submit submit; ...
Наше представление (view) будет использовать эту простую форму:
struct message : public cppcms::base_content { long long int fact; int arg; input_form info; };
И наш темплейт будет очень простым:
<h1>Factorial Calculator</h1> <h2><%= arg %>! = <%= fact %></h2> <form method="post" action="" > <% form as_p info %> </form>
Код
Код будет состоять из двух частей:
- Получение новых данных
- Обработка закэшированных данных
Для начала проинициализируем content
:
content::message c; c.arg=0; c.fact=1;
Затем загрузим форму:
if(request().request_method()=="POST") { c.info.load(context()); if(c.info.validate()) { c.arg=c.info.arg.value(); c.info.clear(); }
Мы загружаем от пользователя значение arg
, чтобы знать, что вычислять.
Теперь, если проверка не пройдена, нам ни к чему больше использовать закэшированные данные, мы рендерим вывод и заканчиваем:
else { // Кэш не должен использоваться render("message",c); return; } }
Теперь, получив значение, мы должны вычислить факториал для тестирования, если мы уже делали это и он в кэше:
std::ostringstream key; key << "factorial_" << c.arg; if(cache().fetch_page(key.str())) return;
Если он к кэше, fetch_page
вернет true и изменит вывод на подготовленную страницу.
Замечание: Вы должны обратить внимание, что когда страница извлекается из кэша, она представлена в сжатом или несжатом формате, согласно запросу пользователя. Таким образом, в действительности, вы не только сохраните все операции, необходимые для создания страницы, но также сэкономите на времени сжатия, что может быть существенным для больших страниц.
Теперь, если такого ключа не существует, вычисляем факториал и рендерим вывод:
long long int f=1; for(int i=1;i<=c.arg;i++) { f*=i; } c.fact=f; render("message",c);
Теперь, когда вывод готов, мы можем хранить его в кэше для последующего использования с тайм-аутом 1 час:
cache().store_page(key.str(),3600);
Замечание: В данном конкретном случае мы не обязаны устанавливать тайм-аут, а можем использовать бесконечное значение тайм-аута по-умолчанию и вызвать:
cache().store_page(key.str());
Но в основном динамические страницы устаревают, поэтому мы должны определить тайм-аут или использовать триггеры (триггеры не рассматриваются в данном руководстве).
Очистка кэша
Вы можете удалить записи кэша "воскрешением" их ключей, например:
cache().rise("factorial_10");
удалит запись с ключом factorial_10
из памяти. Но этого не требуется в случае нашей простой программы.
Конфигурация
Для использования кэша, мы должны определить backend кэширования, поэтому добавим в config.js
следующие строки:
"cache" : { "backend" : "thread_shared", "limit" : 100, }
Тип нашего backend'а: thread_shared
. Мы также должны определить его размер как число записей, например 100. См. Configuration::Cache для корректной настройки вашего backend'а кэширования.
Дополнительные материалы
Это основы использования кэша. Вообще система кэширования CppCMS предоставляет гораздо больше:
- Удаление набора ключей с помощью обычных триггеров,
- Автоматическое отслеживание зависимостей различных ключей,
- Сохранение (сериализация) в кэше различных объектов C++,
- Сохранение простых "текстовых фреймов" в кэше для более быстрого рендеринга элементов, типа: sidebar'ов, header'ов, footer'ов, сигнатур и прочего.
См. cppcms::cache_interface и cppcms::triggers_recorder для подробного описания и примеров.