Один ресурс - несколько кэшей

Нетрививальная задача:
а) есть два сайта на одном движке modx
б) все ресурсы в БД modx — общие для этих сайтов, т.е. одни и те же ресурсы (информация об одних и тех же ресурсах) могут отображаться на обоих сайтах
в) на каждом сайте отображается свой набор ресурсов

Т.е. на сайте A отображается информация о ресурсах 5,6,7,15,16,17, на сайте B — 5,15,16,25,28,100,101. Т.е. на каждом из сайтов должен быть доступ ко всем ресурсам.

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

Проблема заключается в том, как организовать кэширование. Предположим, что один и тот же русурс загружается на сайте A и сайте B (на каждом из сайтов этот ресурс отображается по-разному и сопровождается различной информацией). Ресурс один и тот же, но кэши у него должны быть разные (отдельные). Т.е. каждый ресурс должен иметь 2 кэша для каждого из сайтов.

3 варианта организации такого «множественного» кэширования ресурсов:
1.Использование контекстов modx.
Как известно, modx создаёт свой отдельный кэш для каждого из контекстов. Можно для каждого сайта создать свой контекст, а все ресурсы «сложить» в контекст «web».
Но проблема в том, что если переключать контексты в зависимости от сайта, то из этих контекстов не будет доступа к общим ресурсам из контекста «web». А если контексты не переключать, то для разных сайтов кэш будет один и тот же.

2. Управление кэшированием через плагины.
Здесь необходимо решить 3 задачи:
а) для текущего ресурса проверить наличия кэша, соответствующего сайту
б) для текущего ресурса извлечь кэш, соответствующий сайту
в) для текущего ресурса сохранить кэш, соответствующий сайту, изменив (удлинив) имя файла кэша (формируемое по умолчанию)
Последние 2 пункта, возможно, можно решить, используя события OnBeforeSaveWebPageCache и OnLoadWebPageCache. Но в modx не предусмотрено событий, в обработчиках которых возможно повлиять на решение modx о существовании кэша ресурса для соответствующего сайта.

3. Перегрузка методов xPDOCacheManager. Но это уже дебри дремучие, с которыми придётся воевать с каждой новой версией modx.

Как решить задачу «множественного» кэширования ресурсов ?
Cyrax_02
18 июля 2014, 07:45
modx.pro
1
1 821
0

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

Антон Фомичёв
18 июля 2014, 12:12
+1
3. Перегрузка методов xPDOCacheManager. Но это уже дебри дремучие, с которыми придётся воевать с каждой новой версией modx.
Так не надо изменять их прямо в файле MODX. Напиши свою реализацию кэширования, какой-нибудь modMultipleCache, расширяющий xPDOCacheManager. Там опиши все, что тебе необходимо (собственно, и изменять поведение методов родительского класса никто не запрещал). В настройках системы укажи свой класс как отвечающий за кэширование и воевать ни с чем не придётся.
    Cyrax_02
    18 июля 2014, 14:28
    0
    Я как раз и имел ввиду перегрузку. Наследование + перегрузка. Об изменении исходных кодов речи, конечно же, не идёт.
    А войнушки касаются необходимости подстраивать свой код под изменяющуюся от версии к версии логику работы modx. Чем больше используешь тонкостей реализации modx, тем чаще придётся корректировать свой код.
    К примеру, вон вышла новая версия modx 2.3 — так все компоненты, разработанные Василием, приходится корректировать. Потому что внутренняя логика работы modx несколько изменилась.
    Алексей
    18 июля 2014, 13:07
    +1
    Мне кажется, отлавливать кэширование в плагинах не имеет смысла. Вызов ресурсов происходит в сниппите, его нужно вызвать некэшированным
    [[!snippet]]
    и в нем проверить текущий домен. Так же создать кэш можно тоже в сниппите — для каждого домена свой. По-моему getPage работает по подобной схеме, только для каждого url свой кэш, в зависимости от параметра в URL site.com/doc?&page=2 или, к примеру site.com/doc?&page=3 — пишет в разный кэш. Может немного сумбурно объяснил, и наверное где-то ошибся)
      Cyrax_02
      18 июля 2014, 14:37
      0
      Да, этот вариант не упомянул в 1-м посте. Способ самый гибкий.
      Минусы этого варианта:
      1) Всю логику кэширования придётся загонять внутрь сниппетов. Т.е. практически в каждом сниппете придётся реализовывать кэширование.
      2) Отходим от модели кэширования modx. Все эти сниппеты придётся вызывать некэшированными, а логику кэширования реализовывать внутри сниппетов
      3) Придётся для каждого такого сниппета предусматривать и реализовывать параметр &cache для возможности отключения кэширования.

      Т.е. в целом вариант некрасивый и несистемный.
        Василий
        20 июля 2014, 17:23
        +1
        Есть замечательное дополнение getCache, в котором можно самостоятельно указывать ключи для кеша. Делаете на основании домена — используйте его имя или модификацию в качестве префикса ключа.
          Алексей
          22 июля 2014, 01:17
          0
          Как-то юзал его. Но теперь, чтобы не ставить использую pdoPage или getPage- тот же функционал.
            Cyrax_02
            22 июля 2014, 02:49
            0
            Ну уж нет. Лучше всё руками писать.
            Пока остановился на этом варианте как самом гибком. Для каждого сниппета — свой индивидуальный набор зависимых параметров, хэширование и прочее (всё это инкапсулировал в 2 функции, одну вызываю в начале сниппета, другую — в конце). Правда, сниппет всё равно вызывается (одно лишнее обращение к БД), но зато реализовывается тонкая индивидуальная логика кэширования.
      Руслан Кундиус
      21 июля 2014, 01:19
      +2
      Как вариант менять плагином ключ кэша ресурса при событии OnWebPageInit:
      switch ($siteid) {
          case 1:
              $modx->setOption('cache_resource_key', 'resource/site1');
              break;
          case 2:
              $modx->setOption('cache_resource_key', 'resource/site2');
              break;
      }
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        8