Сброс и обновление кэша сниппета в определенное время

Уже когда-то задавался этим вопросом, пришел к такому решению (уже без getCache, но с fenom и включенным pdotools_fenom_parser).

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 утра, тут уже сами гуглите.

Если у кого-то есть более элегантное решение, кидайте в комменты.
Viktor
15 ноября 2019, 21:40
modx.pro
1
1 568
+3

Комментарии: 31

Алексей Соин
15 ноября 2019, 21:54
0
Не совсем понял, а какую проблему решает данный сниппет?
    Viktor
    15 ноября 2019, 22:32
    0
    Смысл в быстродействии.

    У меня так: есть огромная страница, которую нужно спарсить раз в неделю и парсинг занимает много времени, если парсить каждый раз по окончанию действия кэша или ручной очистки кэша с админки, первому посетителю придется ждать десятки секунд (а он не будет ждать). Решил я парсить её cron-ом раз в неделю отдельным php скриптом, результат сохранять в файл на сервере (около 0.5 мб). Таким образом сниппет «snippetName» с примера выше, просто выполняет чтение и возврат этого файла «echo file_get_contents($file);», что существенно ускоряет время загрузки страницы если я очистил кэш вручную или время кэша закончилось. Потом я cron-ом выполняю запуск того самого php скрипта, который сохраняет результат в локальный файл. Вот такой вот многослойный торт.
      Алексей Соин
      15 ноября 2019, 22:40
      0
      а не проще сделать выполняемый с периодичностью по крону php скрипт который парсит данные и записывает результат в контент ресурса или допустим в тв поле?

      Тогда этот скрипт хоть в 3 часа ночи запускай, хоть в 12 дня, когда обработка данных закончится он мигом запишет данные в ресурс и пользователь получит актуальную информацию.
        Viktor
        15 ноября 2019, 22:52
        0
        когда обработка данных закончится он мигом запишет данные в ресурс и пользователь получит актуальную информацию.
        разве после того, как записать результат в контент ресурса, не нужно будет очистить кэш этого ресурса, после этого обновить кэш этого ресурса, чтобы пользователь получил обновленную инфу?
          Алексей Соин
          15 ноября 2019, 22:58
          0
          поидеи менеджер кэша должен отловить изменения и инфа при обновлении данных будет показываться актуальная, проверь, ну в любом случае, даже если у тебя по каким то причинам инфа будет кэшироваться, то после обновления данных можно почистить кэш, это всё равно лучше чем свой вариант велосипеда изобретать.
            Viktor
            15 ноября 2019, 23:38
            0
            1. результат парсинга заносим в контент;
            2. чистим кэш только этого ресурса;
            3. для обновления кэша пользователь должен зайти на страницу и получить задержку в несколько секунд (в моём случае), вместо этого мы заходим на страницу кроном.

            мой велосипед это и делает, кроме заноса прямиком в контент и углубления в API MODX
              Алексей Соин
              15 ноября 2019, 23:47
              0
              ну если ты считаешь, что данный подход лучше чем использовать методы modx, ок.

              я в этом ничего полезного к сожалению не увидел
                Viktor
                16 ноября 2019, 00:20
                0
                для нубов в modx, php или вообще программировании, типа меня, это будет полезным
        Александр
        16 ноября 2019, 03:26
        0
        Вот такой вот многослойный торт.
        Что-то торт слишком многослойный. Решение в теме выглядит бессмыслицей О_О. И в коммент «Смысл в быстродействии» тоже не въехать.
        Я бы, наверно, поставил в крон что-то типа
        $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.php
        public function save($cacheFlag= null) {
        ...
        При сохранении ресурса с флагом $cacheFlag= true, кеш ресурса обновляется. Этим занимается метод toCache в core\xpdo\xpdo.class.php.
        Наверно, можно при сохранении ресурса в админке сразу создавать его кеш. Переделав плагин Василия bezumkin.ru/sections/tips_and_tricks/351/. Только говорят кеш в MODX чистится весь из-за каких-то проблем. И не понятно, какие проблемы могут возникнуть, если кеш делать при сохранении в админке.
          Александр
          16 ноября 2019, 03:40
          0
          Проверил save(true) не работает :-(
          А где делается кеш при загрузке странице в упор не могу найти
            Сергей Шлоков
            16 ноября 2019, 09:11
            3
            +8
            Эх, молодежь. Всё делается гораздо проще. Ставим modHelpers и используем функцию snippet.
            {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 не нужен. И даже вреден. Ибо делает ненужную работу для каждого запроса страницы.

            П.С. И ещё совет. Не пихайте логику во вьюхи. Это бад практис! Перенесите логику в сниппет и вызывайте его на странице.
              Александр
              16 ноября 2019, 21:31
              +1
              А я вот modHelpers не пользуюсь. Пробегался по диагонали по его функциям. Такое впечатление, что это просто синтаксический сахар. То есть, ничего особо полезного не несет. Просто сокращает имена функций MODX. В итоге, и надо знать функции MODX и еще учить синтаксис modHelpers. Что мне не особо хочется.
              Плюс, для совместной работы, надо придерживаться единообразного стиля программирования. Синтаксис php, MODX и fenom знаком многим. А вот modHelpers редко встречается. И, соответственно, его не стоит использовать. Это помешает другим работать над проектом.
                Сергей Шлоков
                17 ноября 2019, 09:39
                +4
                Ты в Laravel не ходи, расстроишься. Там аж две библиотеки хелперов из коробки. И Тейлору ничего не говори. Его твоё мнение может огорчить.

                Такое впечатление, что это просто синтаксический сахар. То есть, ничего особо полезного не несет.
                Боюсь тебя расстроить, но MODX — это синтаксический сахар над PHP. Юзай последний. Не отказывайся от своих принципов.

                И, соответственно, его не стоит использовать. Это помешает другим работать над проектом.
                Не используй. Сделай мне больно.

                П.С. Только щас заметил, что мой коммент почему-то попал не в корень, а залетел в ответ на твой коммент. Видимо глаза уже подводят.
                Александр
                16 ноября 2019, 21:45
                0
                Не пихайте логику во вьюхи. Это бад практис! Перенесите логику в сниппет и вызывайте его на странице.
                В MODX не вьюхи, а чанки. То есть, MODX, вообще-то, не придерживается паттерна MVC.
                Конечно, в чанки не стоит пихать код, но часто бывает так значительно проще. Например, как тут.
                  Александр Мельник
                  16 ноября 2019, 21:56
                  0
                  Выскажу свою согласие c Александром. Зачем тогда пользоваться Fenom, неужели только чтобы заменить [[+name]] на {$name} и зачем в fenom пробрасывали основной объект приложения $modx в $_modx, разве не для того чтобы в чанке или шаблоне дотянуться до методов.
                    Павел Гвоздь
                    17 ноября 2019, 08:38
                    +2
                    Феном полноценный шаблонизатор. Как можно сказать в отношении него «чтобы заменить [[+name]] на {$name}»?

                    Зачем тогда пользоваться Fenom
                    Как минимум ради циклов, расширения шаблонов.

                    пробрасывали основной объект приложения $modx в $_modx
                    microMODX $_modx ≠ modX $modx

                    разве не для того чтобы в чанке или шаблоне дотянуться до методов.
                    Сергей сказал, что это плохая практика, никто не запрещает делать такие сайты в одиночку. Однако в команде за это могут надавать по рукам.
                      Сергей Шлоков
                      17 ноября 2019, 09:29
                      +2
                      Не путай логику отображения с логикой приложения. Последней не место во вьюхах. Вот пример логики отображения.

                      Лично я не вижу особой необходимости в объекте $_modx как ограничителе функциональности для безопасности. Этого нет ни в одном шаблонизаторе. Видимо никому не понадобилась такая фича. А вот как объект для работы со вьюхами (шаблонами, чанками, ресурсами) он хорош. Для правильной работы, если можно так выразится. И юзер $_modx->user там нужен! Хотя я бы сделал юзера отдельным объектом для удобства. Но считаю, что кэшменеджер тут лишний. Вот такое имхо. Но, как правильно сказал Павел, ты может делать что хочешь и как хочешь. Fenom позволяет юзать даже объект $modx. It's up to you.
                        Александр
                        18 ноября 2019, 22:46
                        0
                        А чем логика отображения от логики приложения отличается? Или может все таки граница размыта?
                    Viktor
                    18 ноября 2019, 15:31
                    0
                    смысл differenceBetweenDatesInSeconds в указании количества секунд до точной даты и времени, а не через 604800 сек, потому что если очистить кэш вручную, время жизни кэша обновится и дата сместится.
                      Сергей Шлоков
                      18 ноября 2019, 16:21
                      +1
                      ЧТО делает сниппет differenceBetweenDatesInSeconds все разобрались. Осталось только понять ЗАЧЕМ?
                        Viktor
                        19 ноября 2019, 22:43
                        0
                        например, обновлять по крону глубокой ночью, чтобы ни один поисковый бот или посетитель не получил задержку в несколько секунд
                          Александр
                          19 ноября 2019, 23:03
                          0
                          Таким образом сниппет «snippetName» с примера выше, просто выполняет чтение и возврат этого файла «echo file_get_contents($file);», что существенно ускоряет время загрузки страницы если я очистил кэш вручную или время кэша закончилось
                          1 а сниппет с
                          echo file_get_contents($file);
                          Выполняется не быстрей, чем
                          !$snippet = $_modx->cacheManager->get('snippetName_cache');
                          И у тебя в файле $file уже типо кеш. Зачем его кешировать еще раз на странице. Наверно, можно было 2 ресурс, который показывается, сделать статическим и прикрепить к нему $file.
                  Александр
                  16 ноября 2019, 21:54
                  0
                  Все не могу въехать в логику решения. По моему ты что-то в описании пропустил. Может у тебя 1 страница которая грузиться десятки секунд, а ты пользователю показываешь 2 страницу с твоим сниппетом, который уже показывает распарсенную 1 страницу?
                    Viktor
                    18 ноября 2019, 15:33
                    0
                    верно
                      Viktor
                      19 ноября 2019, 22:57
                      0
                      только я беру вторую страницу не из ресурса, а из обычного html файла, который сохраняю php скриптом, который не использует modx
                        Александр
                        19 ноября 2019, 23:06
                        0
                        епрст. Ты снова запутал. Если 2 страница отдается Apache без MODX, то что делает страница со сниппетом differenceBetweenDatesInSeconds? Или у тебя 3 страницы?
                      Александр
                      16 ноября 2019, 23:44
                      0
                      У меня, сейчас, клиент просит ускорить сайт. И, причем, за небольшие деньги. Соблазняюсь идеей, для тяжелых страниц, сложить в кеш уже сгенерированный код HTML и отдавать его при запросе страницы без get и post параметров. У клиента tagmanager2 втупляет на большом числе товаров. НО как страница загрузилась работает уже быстро. НО и сломать может. mFilter2 такой метод точно сломает (Он свои настройки в сессии хранит. Со статическим кешем сниппет не выполниться и сессия окажется пустой.)
                      первому посетителю придется ждать десятки секунд
                      Что у вас такого тяжелого на странице выполняется? Хочется сделать какое-нибудь универсальное решение проблемы, если это возможно. Действительно тяжелые это фильтры товаров. Какие еще тяжелые сниппеты или случаи есть?
                        Павел Голубев
                        17 ноября 2019, 21:15
                        0
                        а чём тяжесть фильтров товаров?
                          Александр
                          18 ноября 2019, 21:32
                          0
                          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с
                            Александр
                            18 ноября 2019, 21:54
                            0
                            {!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 ресурсов. Ну это уже оптимизированные сайты. На них уже не так тупит.
                            ElenaLelo
                            18 ноября 2019, 09:02
                            0
                            Мне обычно хоть какую то информацию позволяет получить debugParser . Хотя, у меня фильтры везде быстро работают из коробки, более-менее.
                        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                        31