Сброс и обновление кэша сниппета в определенное время
Уже когда-то задавался этим вопросом, пришел к такому решению (уже без getCache, но с fenom и включенным pdotools_fenom_parser).
UPD Зачем вообще это.
Создаем сниппет differenceBetweenDatesInSeconds:
На странице, где вызывается кэшируемый сниппет, пишем:
Потом cron-ом заходим на страницу каждый вторник в, например, 3:05 утра, тут уже сами гуглите.
Если у кого-то есть более элегантное решение, кидайте в комменты.
UPD Зачем вообще это.
Создаем сниппет differenceBetweenDatesInSeconds:
<?php
$fromDate = new DateTime(); //сегодня по времени сервера
$toDate = new DateTime();
$toDate->modify('next tuesday +3 hours'); //в следующий вторник в 3 часа утра
$difference = $toDate->getTimestamp() - $fromDate->getTimestamp(); //разница в секундах между сегодня и 3-мя утра следующего вторника, в это время истечет срок действия кэша
return $difference;
На странице, где вызывается кэшируемый сниппет, пишем:
{var $seconds = '!differenceBetweenDatesInSeconds' | snippet}
{if !$snippet = $_modx->cacheManager->get('snippetName_cache')}
{set $snippet = $_modx->runSnippet('!snippetName', ['someParameter'=>'someValue'])}
{set $null = $_modx->cacheManager->set('snippetName_cache', $snippet, $seconds)}
{/if}
{$snippet}
Потом cron-ом заходим на страницу каждый вторник в, например, 3:05 утра, тут уже сами гуглите.
Если у кого-то есть более элегантное решение, кидайте в комменты.
Комментарии: 31
Не совсем понял, а какую проблему решает данный сниппет?
- результат парсинга заносим в контент;
- чистим кэш только этого ресурса;
- для обновления кэша пользователь должен зайти на страницу и получить задержку в несколько секунд (в моём случае), вместо этого мы заходим на страницу кроном.
Смысл в быстродействии.
У меня так: есть огромная страница, которую нужно спарсить раз в неделю и парсинг занимает много времени, если парсить каждый раз по окончанию действия кэша или ручной очистки кэша с админки, первому посетителю придется ждать десятки секунд (а он не будет ждать). Решил я парсить её cron-ом раз в неделю отдельным php скриптом, результат сохранять в файл на сервере (около 0.5 мб). Таким образом сниппет «snippetName» с примера выше, просто выполняет чтение и возврат этого файла «echo file_get_contents($file);», что существенно ускоряет время загрузки страницы если я очистил кэш вручную или время кэша закончилось. Потом я cron-ом выполняю запуск того самого php скрипта, который сохраняет результат в локальный файл. Вот такой вот многослойный торт.
У меня так: есть огромная страница, которую нужно спарсить раз в неделю и парсинг занимает много времени, если парсить каждый раз по окончанию действия кэша или ручной очистки кэша с админки, первому посетителю придется ждать десятки секунд (а он не будет ждать). Решил я парсить её cron-ом раз в неделю отдельным php скриптом, результат сохранять в файл на сервере (около 0.5 мб). Таким образом сниппет «snippetName» с примера выше, просто выполняет чтение и возврат этого файла «echo file_get_contents($file);», что существенно ускоряет время загрузки страницы если я очистил кэш вручную или время кэша закончилось. Потом я cron-ом выполняю запуск того самого php скрипта, который сохраняет результат в локальный файл. Вот такой вот многослойный торт.
а не проще сделать выполняемый с периодичностью по крону php скрипт который парсит данные и записывает результат в контент ресурса или допустим в тв поле?
Тогда этот скрипт хоть в 3 часа ночи запускай, хоть в 12 дня, когда обработка данных закончится он мигом запишет данные в ресурс и пользователь получит актуальную информацию.
Тогда этот скрипт хоть в 3 часа ночи запускай, хоть в 12 дня, когда обработка данных закончится он мигом запишет данные в ресурс и пользователь получит актуальную информацию.
когда обработка данных закончится он мигом запишет данные в ресурс и пользователь получит актуальную информацию.разве после того, как записать результат в контент ресурса, не нужно будет очистить кэш этого ресурса, после этого обновить кэш этого ресурса, чтобы пользователь получил обновленную инфу?
поидеи менеджер кэша должен отловить изменения и инфа при обновлении данных будет показываться актуальная, проверь, ну в любом случае, даже если у тебя по каким то причинам инфа будет кэшироваться, то после обновления данных можно почистить кэш, это всё равно лучше чем свой вариант велосипеда изобретать.
мой велосипед это и делает, кроме заноса прямиком в контент и углубления в API MODX
ну если ты считаешь, что данный подход лучше чем использовать методы modx, ок.
я в этом ничего полезного к сожалению не увидел
я в этом ничего полезного к сожалению не увидел
для нубов в modx, php или вообще программировании, типа меня, это будет полезным
Вот такой вот многослойный торт.Что-то торт слишком многослойный. Решение в теме выглядит бессмыслицей О_О. И в коммент «Смысл в быстродействии» тоже не въехать.
Я бы, наверно, поставил в крон что-то типа
$res_id = 1; // id нужного ресурса
define('MODX_API_MODE', true);
require_once $_SERVER['DOCUMENT_ROOT']."/index.php";
if($res = $modx->getObject("modResource",$res_id){
$res->save(true);
}
из core\model\modx\modresource.class.phppublic function save($cacheFlag= null) {
...
При сохранении ресурса с флагом $cacheFlag= true, кеш ресурса обновляется. Этим занимается метод toCache в core\xpdo\xpdo.class.php.Наверно, можно при сохранении ресурса в админке сразу создавать его кеш. Переделав плагин Василия bezumkin.ru/sections/tips_and_tricks/351/. Только говорят кеш в MODX чистится весь из-за каких-то проблем. И не понятно, какие проблемы могут возникнуть, если кеш делать при сохранении в админке.
Проверил save(true) не работает :-(
А где делается кеш при загрузке странице в упор не могу найти
А где делается кеш при загрузке странице в упор не могу найти
Эх, молодежь. Всё делается гораздо проще. Ставим modHelpers и используем функцию snippet.
А в cron удаляем кэш и парсим страницу сниппетом
Функция snippet() сама проверит кэш. Если его нет, то выполнит указанный сниппет и результат сохранит в кэш. И не нужно вычислять все эти секунды. Cron каждую неделю будет обновлять кэш независимо от того, есть он или нет. Поэтому сниппет differenceBetweenDatesInSeconds не нужен. И даже вреден. Ибо делает ненужную работу для каждого запроса страницы.
П.С. И ещё совет. Не пихайте логику во вьюхи. Это бад практис! Перенесите логику в сниппет и вызывайте его на странице.
{snippet("mySnippet", ["param" => "value"], 604800)} // сохраняем на неделю. Третий параметр лучше указать через массив (см. ниже)
А в cron удаляем кэш и парсим страницу сниппетом
... // инициализация MODX
// Лучше указать отдельную папку для хранения данных. Иначе данные будут лежать в папке cache/default, которая очищается при сохранении любого объекта MODX.
$options = array(
cache_key => 'mysnippet_cache',
cache_expires => 604800,
);
cache()->delete("mySnippet", $options);
snippet("mySnippet", ["param" => "value"], $options);
Что важно! В данном случае сам сниппет на странице вызывается некэшированным. Поэтому кэш самой страницы обновлять не нужно. Только кэш сниппета!!! Обратите внимание, насколько код стал проще.Функция snippet() сама проверит кэш. Если его нет, то выполнит указанный сниппет и результат сохранит в кэш. И не нужно вычислять все эти секунды. Cron каждую неделю будет обновлять кэш независимо от того, есть он или нет. Поэтому сниппет differenceBetweenDatesInSeconds не нужен. И даже вреден. Ибо делает ненужную работу для каждого запроса страницы.
П.С. И ещё совет. Не пихайте логику во вьюхи. Это бад практис! Перенесите логику в сниппет и вызывайте его на странице.
А я вот modHelpers не пользуюсь. Пробегался по диагонали по его функциям. Такое впечатление, что это просто синтаксический сахар. То есть, ничего особо полезного не несет. Просто сокращает имена функций MODX. В итоге, и надо знать функции MODX и еще учить синтаксис modHelpers. Что мне не особо хочется.
Плюс, для совместной работы, надо придерживаться единообразного стиля программирования. Синтаксис php, MODX и fenom знаком многим. А вот modHelpers редко встречается. И, соответственно, его не стоит использовать. Это помешает другим работать над проектом.
Плюс, для совместной работы, надо придерживаться единообразного стиля программирования. Синтаксис php, MODX и fenom знаком многим. А вот modHelpers редко встречается. И, соответственно, его не стоит использовать. Это помешает другим работать над проектом.
Ты в Laravel не ходи, расстроишься. Там аж две библиотеки хелперов из коробки. И Тейлору ничего не говори. Его твоё мнение может огорчить.
П.С. Только щас заметил, что мой коммент почему-то попал не в корень, а залетел в ответ на твой коммент. Видимо глаза уже подводят.
Такое впечатление, что это просто синтаксический сахар. То есть, ничего особо полезного не несет.Боюсь тебя расстроить, но MODX — это синтаксический сахар над PHP. Юзай последний. Не отказывайся от своих принципов.
И, соответственно, его не стоит использовать. Это помешает другим работать над проектом.Не используй. Сделай мне больно.
П.С. Только щас заметил, что мой коммент почему-то попал не в корень, а залетел в ответ на твой коммент. Видимо глаза уже подводят.
Не пихайте логику во вьюхи. Это бад практис! Перенесите логику в сниппет и вызывайте его на странице.В MODX не вьюхи, а чанки. То есть, MODX, вообще-то, не придерживается паттерна MVC.
Конечно, в чанки не стоит пихать код, но часто бывает так значительно проще. Например, как тут.
Выскажу свою согласие c Александром. Зачем тогда пользоваться Fenom, неужели только чтобы заменить [[+name]] на {$name} и зачем в fenom пробрасывали основной объект приложения $modx в $_modx, разве не для того чтобы в чанке или шаблоне дотянуться до методов.
Феном полноценный шаблонизатор. Как можно сказать в отношении него «чтобы заменить [[+name]] на {$name}»?
Зачем тогда пользоваться FenomКак минимум ради циклов, расширения шаблонов.
пробрасывали основной объект приложения $modx в $_modxmicroMODX $_modx ≠ modX $modx
разве не для того чтобы в чанке или шаблоне дотянуться до методов.Сергей сказал, что это плохая практика, никто не запрещает делать такие сайты в одиночку. Однако в команде за это могут надавать по рукам.
Не путай логику отображения с логикой приложения. Последней не место во вьюхах. Вот пример логики отображения.
Лично я не вижу особой необходимости в объекте $_modx как ограничителе функциональности для безопасности. Этого нет ни в одном шаблонизаторе. Видимо никому не понадобилась такая фича. А вот как объект для работы со вьюхами (шаблонами, чанками, ресурсами) он хорош. Для правильной работы, если можно так выразится. И юзер $_modx->user там нужен! Хотя я бы сделал юзера отдельным объектом для удобства. Но считаю, что кэшменеджер тут лишний. Вот такое имхо. Но, как правильно сказал Павел, ты может делать что хочешь и как хочешь. Fenom позволяет юзать даже объект $modx. It's up to you.
Лично я не вижу особой необходимости в объекте $_modx как ограничителе функциональности для безопасности. Этого нет ни в одном шаблонизаторе. Видимо никому не понадобилась такая фича. А вот как объект для работы со вьюхами (шаблонами, чанками, ресурсами) он хорош. Для правильной работы, если можно так выразится. И юзер $_modx->user там нужен! Хотя я бы сделал юзера отдельным объектом для удобства. Но считаю, что кэшменеджер тут лишний. Вот такое имхо. Но, как правильно сказал Павел, ты может делать что хочешь и как хочешь. Fenom позволяет юзать даже объект $modx. It's up to you.
А чем логика отображения от логики приложения отличается? Или может все таки граница размыта?
смысл differenceBetweenDatesInSeconds в указании количества секунд до точной даты и времени, а не через 604800 сек, потому что если очистить кэш вручную, время жизни кэша обновится и дата сместится.
ЧТО делает сниппет differenceBetweenDatesInSeconds все разобрались. Осталось только понять ЗАЧЕМ?
например, обновлять по крону глубокой ночью, чтобы ни один поисковый бот или посетитель не получил задержку в несколько секунд
Таким образом сниппет «snippetName» с примера выше, просто выполняет чтение и возврат этого файла «echo file_get_contents($file);», что существенно ускоряет время загрузки страницы если я очистил кэш вручную или время кэша закончилось1 а сниппет с
echo file_get_contents($file);
Выполняется не быстрей, чем !$snippet = $_modx->cacheManager->get('snippetName_cache');
И у тебя в файле $file уже типо кеш. Зачем его кешировать еще раз на странице. Наверно, можно было 2 ресурс, который показывается, сделать статическим и прикрепить к нему $file.
Все не могу въехать в логику решения. По моему ты что-то в описании пропустил. Может у тебя 1 страница которая грузиться десятки секунд, а ты пользователю показываешь 2 страницу с твоим сниппетом, который уже показывает распарсенную 1 страницу?
верно
только я беру вторую страницу не из ресурса, а из обычного html файла, который сохраняю php скриптом, который не использует modx
епрст. Ты снова запутал. Если 2 страница отдается Apache без MODX, то что делает страница со сниппетом differenceBetweenDatesInSeconds? Или у тебя 3 страницы?
У меня, сейчас, клиент просит ускорить сайт. И, причем, за небольшие деньги. Соблазняюсь идеей, для тяжелых страниц, сложить в кеш уже сгенерированный код HTML и отдавать его при запросе страницы без get и post параметров. У клиента tagmanager2 втупляет на большом числе товаров. НО как страница загрузилась работает уже быстро. НО и сломать может. mFilter2 такой метод точно сломает (Он свои настройки в сессии хранит. Со статическим кешем сниппет не выполниться и сессия окажется пустой.)
первому посетителю придется ждать десятки секундЧто у вас такого тяжелого на странице выполняется? Хочется сделать какое-нибудь универсальное решение проблемы, если это возможно. Действительно тяжелые это фильтры товаров. Какие еще тяжелые сниппеты или случаи есть?
а чём тяжесть фильтров товаров?
1 [[!tmFilters? &filterOuterTpl=`public. tm2_filterOuterTpl` &filterTpl=`public. tm2_filterTpl` &filterNumericOuterTpl=`public. tm2_filterOuterTpl` &filterNumericTpl=`public. tm2_filterNumericTpl` &jsMap=`1` &jsScript=`1` &style=`0` &toPlaceholder=`filters` &categoryId=`[[!getCurrentCategoryID]]` &parents=`[[!getCurrentCategoryID]]` ]] 3 0.0017819 1.7729151
2 [[!tmCatalog? &tvFilters=`[[!getAutomaticProductParamType? return=`json` &tvid=`57,58`]]` ]] 4 0.0014601 0.3016510
Вот данные с тагманегер. Всего 30 000 ресурсов.1.7729151 немного. но почему-то временами втупляет до 10с
{!CustomFilter2 | snippet : Array ( [class] => msProduct [element] => msProducts [limit] => 40 [sortby] => Array ( [availability] => ASC [image] => DESC ) [tpls] => @FILE chunks/catalog/_item.col.tpl [suggestions] => [tplOuter] => @FILE chunks/catalog/_outer.tpl [showEmptyFilters] => [filter_delimeter] => - [mse2_frontend_js] => /assets/scripts/mseach2.js [showHidden] => 1 [cache] => 1 [minQuery] => 1 [ajax] => 1 [aliases] => ms-brand==brand, ms-country==country, ms-price==price, ms-weight==weight, ms-size_width==width, ms-size_height==height, ms-size_depth==depth, ms-power==power, ms-voltage==voltage, ms-availability==availability, ms-equipment_type==equipment_type, msoption-size==size, msoption-color==color, ms-favorite==favorite [filters] => ms-favorite:boolean, ms-availability, ms-brand, ms-country, ms-price:number, ms-weight:number, ms-size_width:number, ms-size_height:number, ms-size_depth:number, ms-power:number, ms-voltage, -msoption-size, -msoption-color [tplFilter.outer.default] => @FILE chunks/catalog/_filter.checkbox.outer.tpl [tplFilter.row.default] => @FILE chunks/catalog/_filter.checkbox.row.tpl [tplFilter.outer.price] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.weight] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.width] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.height] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.depth] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.power] => @FILE chunks/catalog/_filter.number.outer.tpl [tplFilter.outer.size] => @FILE chunks/catalog/_filter.size.outer.tpl [tplFilter.outer.color] => @FILE chunks/catalog/_filter.color.outer.tpl [tplFilter.row.price] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.weight] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.width] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.height] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.depth] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.power] => @FILE chunks/catalog/_filter.number.row.tpl [tplFilter.row.availability] => @FILE chunks/catalog/_filter.availability.row.tpl [tplFilter.row.color] => @FILE chunks/catalog/_filter.color.row.tpl [tplPageFirst] => [tplPageLast] => [tplPageFirstEmpty] => [tplPageLastEmpty] => [tplPagePrevEmpty] => [tplPageNextEmpty] => ) } 133 0.6674600 1.1214080
mFilter2 переделанный кем-то. 88529 ресурсов. Ну это уже оптимизированные сайты. На них уже не так тупит.
Мне обычно хоть какую то информацию позволяет получить debugParser . Хотя, у меня фильтры везде быстро работают из коробки, более-менее.
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.