cacheRegenerator. Авторегенерация кеша страниц

Сегодня публикую маленький, но очень полезный компонент (надеюсь в течение дня будет одобрен в modstore.pro). Сейчас это всего один плагин. Задача его состоит в том, чтобы сразу после сохранения документа выполнять регенерацию этой страницы, чтобы даже при первом заходе посетителя, документ уже был в кеше и отдавался быстрее.

Зачем это нужно? Покажу наглядно.
Вот у нас сайт некоторое время поработал и большинство страниц идет из кеша.


Но тут мы отредактировали и сохранили один документ. Что произошло? Сбросился кеш для всех страниц вообще, и теперь при первом заходе на каждую страницу выполняется много лишних действий (первичная выборка данных документа, сниппетов, чанков и прочего из БД, проверка прав и т.п.). Из-за этого скорость генерации страниц сильно падает.


И здесь, казалось бы, возникает простой понятный сценарий: сбрасывать кеш только той страницы, которая редактируется. Но не все так просто… Проблема в том, что эта страница может участвовать в различных выборках (к примеру, новостная лента), и сбросив кеш только этой страницы, но не спросив кеш других страниц, может возникнуть коллизия: на странице обновленной новости будет один контент, а в новостной выборке другой контент. По этой причине очевидно, что необходим функционал не только регенерации текущей редактируемой страницы, но и регенерация всех страниц при полном сбросе кеша сайта. Собственно, этот функционал так же был реализован в этом компоненте, но по умолчанию отключен в системных настройках, так как если страниц много, то при сохранении документа будет долго выполняться запрос на сохранение, а может и вовсе запрос отваливаться по таймлимиту. Автоматическую регенерацию всех страниц имеет смысл включать только если на сайте всего несколько десятков страниц.

Итак, есть три основных режима:
1. Полный сброс кеша при редактировании страницы и автоматическая регенерация всех страниц.
Для этого должна быть включена системная настройка cacheregenerator.regenerate_docs_on_doc_save

2. Регенерация только текущего редактируемого документа. При этом кеш остальных документов не сбрасывается.
Соответственно настройка cacheregenerator.regenerate_docs_on_doc_save должна быть отключена.

3. Автоматическая регенерация всех страниц при ручном вызове сброса кеша сайта.
Должна быть включена настройка cacheregenerator.regenerate_docs_on_site_refresh

Но наиболее правильная, на мой взгляд конфигурация: отключить системную настройку syncsite_default и все. В этом случае при сохранении документа не будет выполняться сброс кеша всех документов. При сохранении cacheRegenerator будет сбрасывать кеш только текущего документа и заново его регенерировать. Тогда не придется переживать за то, что после каждого сохранения документа сбрасывается полностью кеш. Только надо не забывать сбрасывать кеш вручную, если надо будет, чтобы все зависимые документы тоже обновились. Вот тогда после сохранения документа остальные документы будут по прежнему из кеша отдаваться.


Кстати, с syncsite_default отдельный казус:) Если его отключить, то не только всех документов не скидывается кеш, но и текущего редактируемого. То есть в случае отключения этой настройки, даже для редактируемого документа, чтобы изменения вступили в силу, приходится вручную сбрасывать кеш. Эту проблему пришлось тоже решать.

На самом деле подводных камне здесь оказалось много…
Там и проверка доступа к документу неавторизованных пользователей, и правильное кеширование документов в цикле (надо правильно скидывать временные свойства объекта $modx), и прочие «приятные» мелочи. Без учета их то документы с единым контентом сохранялись, то скрипт отваливался, то еще что).
Отдельная песня — перехват заголовков. Ведь при вызове документа может срабатывать какой-нибудь сниппет с проверками прав (типа сброс пароля, к примеру), и тот отдает 404 или 401, из-за чего так же скрипт отваливался. Пришлось хак прописать со сбросом буферизации вывода и выводить простой пробел, чтобы заголовки не отправлялись. В общем этот компонент скушал весьма не мало времени. Я искренне надеюсь, что он будет полезен многим.

Еще момент: есть системные настройки cacheregenerator.exclude_doc_templates_id (можно через запятую указать id-шники шаблонов, документы с которыми исключить из регенерации), cacheregenerator.exclude_docs_id (так же список id-шников документов через запятую, которые исключить надо), и cacheregenerator.regenerate_unsearchable_docs (исключить документы, не доступные для поиска (как правило это всякие технические документы)). Это надо, так как не все получается перехватить и сниппеты с вызовом редиректов и т.п. могут обрывать выполнение скрипта. Вот такие документы и надо исключать.

Цена на него относительно не высокая — 990 рублей, и будет долго такой оставаться (расчет на массовость). Если интерес будет, добавим механизм консольной перегенерации документов. Сейчас такое у нас реализовано на отдельном проекте базе modImporter.


P.S. Компонент опубликован в modstore.pro

UPD Уточнение: на скриншотах не cacheRegenerator, а modMonitor. С помощью монитора я показываю результат работы компонента, но сам cacheRegenerator не имеет интерфейсов.
Fi1osof
13 декабря 2016, 08:04
modx.pro
5
4 951
+16

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

Raimei
13 декабря 2016, 16:32
0
Великолепно, куплю при первой возможности!

P.S. Глупый вопрос наверное, но со страницами от miniShop'а и подобным им конфликтов не будет?
    Fi1osof
    13 декабря 2016, 16:36
    0
    Нет, не приведет. Принцип работы компонента в том, что от анонимного пользователя вызывается отработка документа, как будто на нее зашли извне. То есть если документ нормально работает, то все отработается нормально. А если вдруг что-то не так будет, пишите в поддержку, обязательно разберемся.
    Сергей Шлоков
    13 декабря 2016, 19:48
    1
    +18
    Дежавю? Надо было просить за это деньги.
      Fi1osof
      14 декабря 2016, 10:20
      -1
      С тем же самым успехом можно приходить со своим сайтом-визиткой к гуглу, к примеру, и говорить «Да я уже это делал»… За то, что у тебя сделано, я бы тоже постеснялся брать денег.

      Давай по порядку.
      Во-первых, у тебя там всего три строчки на «создание кеша».
      public function createResourceCache($uri = '/') {
          $siteUrl = $this->modx->getOption('site_url');
          /** @var modRestCurlClient $client */
          $client = $this->modx->getService('rest.modRestCurlClient');
          $result = $client->request($siteUrl, $uri, 'POST');
      }
      То есть простой запрос на УРЛ документа (кстати, об этом еще чуть ниже будет сказано).

      У меня же плагин 200+ строк кода. Для того, чтобы сгенерировать кеш документа, я не шлю какие-то GET-запросы на внешние ресурсы, а именно гененерирую кеш на уровне выполнения самого скрипта. И там поверь, очень много тонкостей.

      У тебя возникает вопрос нафига вообще так все усложнять? Почему не слать простой запрос? Я отвечу. Во-первых, задача ставилась не только генерировать кеш текущего редактируемого документа, но и кеш остальных документов тоже. Но ты, видимо, этого в статье не увидел, «дежавю» ослепило тебя. Вот смотри, что происходит при сохранении документа после полного сброса кена при включенной настройке генерации кеша всех документов (или настройке регенерации при полном сбросе кеша):


      После чего даже все другие документы доступны сразу из кеша:


      Ткни пальцем, где твой компонент умеет генерировать кеш остальных документов?

      Кстати, тебе на заметку: при вызове обновления документов через процессоры напрямую, твой плагин не генерит кеш документа, потому что ты проверяешь глобальную $_POST['createCache'], а не $resource->get('createCache'). Не знал, что обновляемым объектам все передаваемые в процессор параметры присваиваются? Просто в БД не пишется лишнего.

      Во-вторых, слышал про мультидоменность и мультиконтекстность? Давай посмотрим, что происходит при сохранении документов с твоим великим плагином?
      Ой, 404-ая. А при заходе на документ по реальной ссылке во фронте, получаем его не из кеша.


      А с моим плагином как? А с моим все хорошо. Он корректно определил контекст и сформировал корректный запрос.


      Так что конечно можешь продолжать бесплатно свое раздавать. Оно же работает кое-как. Это нормально. А когда сделаешь, чтобы работало как у меня, тогда посмотрим насколько оно у тебя будет бесплатное, и не похожее на то, как у меня сделано.

      И еще: если вдруг ты доработаешь свое «творение», и оно будет «генерировать» кеш всех документов, как именно ты это будешь делать? Так же слать GET-запросы? То есть на сайте 100 документов, 10 раз отредактировал страницу, ушло 10 раз по 100 запросов на сайт? Мало того, что это 1000 инициализаций MODX-а, так это еще и 1000 записей сессий в БД. А будет 10 человек работать, по 100 сохранений в день? 10*100*100 = 100 000 записей в БД за день? Ну-ну…

      P.S. И не думай, что я «идею» подсмотрел у тебя. Поверь на слово, это не так. Я далеко не все твои топики читаю.
        Сергей Шлоков
        14 декабря 2016, 11:18
        1
        +8
        Куда уж нам смердам до тебя. Величие твое расходится вокруг волнами и оседает на нас благодатью.
        P.S. И не думай, что я «идею» подсмотрел у тебя. Поверь на слово, это не так. Я далеко не все твои топики читаю.
        И мысли такой не было. Да и Боб Рей со своим refreshCache вряд ли так думает.
        Да и без разницы мне чего ты и за сколько делаешь. У меня нет ни желания ни права указывать. Мой комментарий выше не для тебя был (ты вроде обещал их игнорировать). Мы все делаем компоненты для пользователей. Им и выбирать. Смысла в перепалке не вижу.
          Fi1osof
          14 декабря 2016, 11:34
          +1
          Да и Боб Рей со своим refreshCache вряд ли так думает.
          Боб так же использует cURL. Повторюсь, я не разделяю этого подхода.

          ты вроде обещал их игнорировать
          Ты приходишь в мой топик и своим комментарием говоришь «Ха, это все фигня, у меня такое же есть, за что тут вообще денег брать?».
          Это не тот случай, когда я могу не обращать внимания на комментарии.
        Fi1osof
        14 декабря 2016, 10:25
        -1
        И давай больше минусов топику и комментам. От этого твои компоненты конечно же лучше станут, а ты умнее.
          Сергей Шлоков
          14 декабря 2016, 11:20
          +5
          Я в этом топике ни одного минуса не поставил. Я вообще не сторонник этого.


          П.С. Что же за жизнь у тебя такая, если ты вместо слов человеческих гавкаешь как собака на всех.
            Fi1osof
            14 декабря 2016, 11:38
            0
            Я не гавкаю.

            Я в этом топике ни одного минуса не поставил. Я вообще не сторонник этого.
            ОК, забираю свои слова обратно. Я тоже этого не придерживаюсь.
            joxi.ru/1A5be4ahnKDRDr

            Просто странно стало, что пока тебя не было, не было и минусов, а потом вдруг раз, и сразу куча упала. Видимо кто-то тут шайками промышляет. Ну да фиг с ним.
              Владимир
              14 декабря 2016, 11:59
              +1
              В порядке взгляда со стороны:
              Просто странно стало, что пока тебя не было, не было и минусов, а потом вдруг раз, и сразу куча упала. Видимо кто-то тут шайками промышляет. Ну да фиг с ним.
              давно заметил, что есть тут такая тенденция ставить минусы за то что услугу\продукт продают, ну вот просто за факт продажи — минус, а так как Сергей ссылался на свой бесплатный компонент, то тут и началось, что де кто-то продает, а оно вон есть даром))
              К огромному сожалению, эмоции и какие то непонятные ожидания халявы и чудес властвуют над умами))
              Всем добра и плюсы. Спасибо за полезные разработки.
                Fi1osof
                14 декабря 2016, 12:04
                0
                давно заметил, что есть тут такая тенденция ставить минусы за то что услугу\продукт продают, ну вот просто за факт продажи — минус,
                Если бы минуса были только к топику, то было бы оправдано. Но к этому комменту с чего минуса? За то, что я ответил человеку? Пришел утром, а там +1/-5.Что за фигня?
                  Владимир
                  14 декабря 2016, 12:12
                  0
                  Николай, активность проявляют люди разные, и, увы, «заминусовать» — склонные ***, но они активнее адекватных, вдумчивых и благодарных. И минусут все и вся, и то что даром, и что за деньги, и где нет ни грамма чего то дискуссионного. Наверно природа такова.
                  PS нужен искусственный интеллект для вычисления веса плюса и минуса)))

                    Fi1osof
                    14 декабря 2016, 12:17
                    0
                    PS нужен искусственный интеллект для вычисления веса плюса и минуса)))
                    Это точно.
        Сергей
        27 декабря 2016, 13:17
        +1
        Добрый день!
        Есть пример сайта, на котором установлен этот модуль, для проверки его скорости загрузки.
          Fi1osof
          27 декабря 2016, 16:31
          +2
          Добрый день.
          Это вопрос или утверждение? Если вопрос, то здесь скриншотов довольно много. Уточню, что этот компонент не добавит вам скорости там, где ее нет. Он просто позволяет не терять ее там, где обычно теряется. Поэтому, если у вас сайт медленно отдает страницы даже из кеша, он не прибавит им скорости.
          Александр
          20 января 2017, 21:49
          +1
          Здравствуйте.
          Подскажите, пожалуйста, как будет работать cacheRegenerator на сайте с количеством ресурсов 2.2к?
            Fi1osof
            22 января 2017, 11:24
            +1
            Александр, здравствуйте.

            Как я и говорил, на таком количестве не стоит включать настройки cacheregenerator.regenerate_docs_on_site_refresh и cacheregenerator.regenerate_docs_on_doc_save, иначе на сохранение документа и на сброс кеша сайта у вас будет запускаться механизм регенерации страниц, который в среднем занимает 1 сек на страницу (в зависимости от скорости работы сайта). Таким образом полчаса ждать после сохранения документа — вообще не вариант.

            Вариант только такой: отключаете системную настройку syncsite_default и при сохранении редактируемого документа не будет сбрасываться кеш остальных документов, а только текущего, при чем у текущего документа кеш сразу будете перегенерирован. Таким образом вы получаете измененное содержимое страницы сразу в кеше.
              Александр
              22 января 2017, 14:11
              0
              Я понял. Спасибо за ответ. К сожалению, мне нужно обновление кэша всех страниц. А ждать полчаса — не вариант.
                Fi1osof
                22 января 2017, 14:26
                +1
                Так или иначе, в любом случае при генерации кеша такого количества страниц придется столько ждать. Ведь генерация кеша страниц — это по сути заход на страницу, и если у вас страницу не из кеша отдает за секунду, то все страницы перегенерить — 1 сек * кол-во страниц, в вашем случае это 2000 секунд. Если отдает за 0.2 сек, то в пять раз меньше времени.

                В общем, я тут думал как вам помочь, и вспомнил, что давным-давно Илья Уткин дописывал функционал циклического выполнения кода в консоль (За что Илье отдельное спасибо). ilyaut.ru/cheats/step-by-step-the-script-in-console/

                В итоге я написал вот такой скрипт: gist.github.com/Fi1osof/398e64212f1c527958adce83734ddf4b
                Его можно использовать для ручной перегенерации кеша всех страниц. Если его запустить, он получит ID-шники всех целевых страниц и перегенерирует их кеш. Выглядит процесс довольно симпатично.


                Вот можете воспользоваться этим скриптом. Сохраните его в консоли (функционал такой добавил Сергей Шлоков) и выполняйте когда вам надо.

                Повторю логику: для того, чтобы не сбрасывался кеш на каждый чих, сделайте как я написал выше. А если вам надо вдруг сбросить кеш всего сайта вручную, то можете запустить потом этот скрипт. Если вам не хочется ждать по полчаса каждый раз, вы можете добавить в условие выборки только самые нагруженные ресурсы (к примеру, по определенным шаблонам).

                Кстати, здесь сразу идея возникает связки этого скрипта с modMonitor. Монитор собирает статистику какие страницы не из кеша отдаются долго, и потом при запуске этого скрипта перегенерируются только те страницы, время генерации которых превышает заданный парог. Получится интеллектуально.

                Важно: Для работы требуется минимум console-2.2.1
                Ее я отправил на modx.com, но пока еще не опубликовали. Можно вручную подправить в консоли вот этот код.
            Гриборий
            15 февраля 2017, 12:34
            0
            Николай, на скринах CMP этого компонента? Или из modMonitor'a?
              Fi1osof
              15 февраля 2017, 13:17
              0
              modMonitor
              Константин
              08 апреля 2017, 21:36
              0
              Боюсь спросить, но где эта панель «Вызываемые элементы»? Установил компонент и уже минут 15 ищу туплю.
                Fi1osof
                08 апреля 2017, 21:58
                0
                Константин, вот прям одним комментарием выше спрашивали про это. На скриншотах не cacheRegenerator, а modMonitor. С помощью монитора я показывал результат работы компонента.

                Добавил уточнение в топик.
                  Константин
                  09 апреля 2017, 00:40
                  0
                  Спасибо! Извиняюсь за невнимательность.
                    Fi1osof
                    09 апреля 2017, 01:57
                    0
                    Ничего страшного.
                Rus
                Rus
                18 июля 2017, 16:11
                0
                Компонент больше не продается? Не смог найти в маркетплейсе modstore.pro.
                Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                28