We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22797
    • 134 Posts
    I was reading in the Zend framework documentation about the ability to tag documents as belonging to certain user-defined cache groups, so that you could selectively purge the cache of only the appropriate documents that have a given tag (see http://framework.zend.com/manual/en/zend.cache.theory.html#zend.cache.tags). Is there an equivalent functionality in Revolution (in existence already or planned)?
      • 22303 MODX Staff
      • 10,725 Posts
      There are many different caching features in Revolution at the moment, but I do not currently have a tag feature for clearing the cache. However, different aspects of the caching can be extended with user-defined classes, so it is possible to implement this kind of feature in custom component cache mechanisms (i.e. where you cache your own custom data), just not throughout the entire core.

      First, lets take a look at all of the things in the core/cache/ directory of Revolution (or core/cache/MODX_CONFIG_KEY/ if you have that set to something other than ’config’)


      Configuration Cache
      In the root you will find the config.cache.php which contains the system settings which are loaded on any request.

      Context Configuration, Event Map, and Plugin Caching
      In a subdirectory for each context (i.e. web/ or mgr/ or connector/) you will find a context.cache.php file containing the context settings, a plugin event map for the context, and the plugin elements that are registered in the event map.

      Resource (Partial-Page) Caching
      Within the web context (or another custom front-end context) there will be a subdirectory for resources/ containing files like 1.cache.php where the 1 represents the id of the resource. These files contain the resource object as well as any cached element output used by the resource.

      Element Caching
      Within each context you will also find an elements/ subdirectory containing cache files for various kinds of elements (especially snippets and plugins). These contain various kinds of cache files which the element classes make use of when they are being processed. For instance, snippets and plugins both cache a generated global function which is included and made available at runtime.

      xPDO Object and Database Result Set Caching
      If you enable this, xPDO can cache query result sets representing any objects and collections in the objects subdirectory. This can be enabled in environments where database access is more expensive than PHP include time. This is separate from all of the other caching mechanisms which are very specific to the operation of MODx.

      Programmatic Caching
      xPDOCacheManager and the modCacheManager class derived from it provide some useful features for caching any kind of data to just about any cache system and includes a memcached implementation. There is no tagging feature here as in the programmatic features of the Zend_Cache library but there are definitely some ways to clear specific parts of any custom caching, as well as various parts of the MODx-specific caching mechanisms described above.


      Now, here are some examples of using modCacheManager->clearCache():
      <?php
      // get the cacheManager
      $cacheManager= $modx->getCacheManager();
      
      // clear all the usual stuff by default (all files with the extension .cache.php in the cachePath + all object caches)
      $cacheManager->clearCache();
      
      // clear only cache files with extension .php or .log in the web/ custom/ or logs/ paths; no objects are cleared
      $paths = array('web/', 'custom/', 'logs/');
      $options = array('objects' => null, 'extensions' => array('.php', '.log'));
      $cacheManager->clearCache($paths, $options);
      
      // clear all cache files with extension .php in the cachePath + all objects + execute the timed publishing checks
      $paths = array('');
      $options = array('objects' => '*', 'publishing' => true, 'extensions' => array('.php'));
      $cacheManager->clearCache($paths, $options);
      ?>


      I’ll let you digest this and we can begin a dialog from there...
        • 22797
        • 134 Posts
        Thank you for the detailed response. Revolution does have a much more advanced set of caching features than the current version of MODx, which is a significant step forward. All of the caching mechanisms you highlighted are important ones.

        Since I use the current version on a daily basis, and only experiment with Revolution when I have time -- which isn’t very often -- my clearest frame of reference is the current version. The all-or-nothing approach there is overly simplistic, and it’s a bit frustrating to have to clear the cache for the entire site when saving a file. I know that I can uncheck the "clear cache" option when saving a page, but then if that particular page was cached, I’ll have to clear the cache anyway, and at that point, the cache for the whole site is wiped out, degrading the performance across the board, until the cache can be rebuilt again.

        In terms of saving pages, I suppose an ideal situation would be to have a mechanism such as tagging (or something similar) that would clear the cache only for the files that are affected. If you have a page describing a product, for example, and need to update the price of the product -- in a template variable, for example -- the cache would need to be cleared for that page plus any page that refers to that product, such as a list of products. But nothing else needs to be cleared.

        Something to facilitate that kind of granularity would be nice. In theory, tags could be applied to configuration files, resources, plugins, elements, and all other modx components. When the time comes to clear tag x, all items with that tag would be cleared.
          • 22797
          • 134 Posts
          Just to extend my previous post, here are a few related ideas.

          When saving snippets, chunks, template variables or templates, the logical default option should probably be to clear the cache only for the resources/pages using those elements.

          There’s more than one to accomplish this. Here are a few thoughts:


          • Maybe a global search could be performed every time one of the elements is saved (e.g. looking for all instances of a given snippet). That might turn out to be unacceptably slow on large sites.
          • The act of saving a resource/page could automatically generate a list of the associated elements, which would be stored in a database field. This would be a way to automatically generate tags for every resource.
          • The user could create the tags manually when saving the resource/page, and would manually specify which tags to clear the cache for when saving the element.

          I think I’d vote for a combination of the second and third option. It would be nice to have Modx automatically generate tags, but give the user the option of overriding or customizing the tags. Then for all elements and resources, have a group of checkbox options that allows the user to specify which caches to clear. Something along these lines:

          When saving this page, clear the cache for:
          __ This [template/resource/snippet/chunk/TV/etc...]
          __ All items that use this [template/resource/snippet/chunk/TV/etc...]
          __ All items with the following cache tag(s) __________________
          Apply the above actions to:
          __ All items in this context
          __ All items across all contexts

          Here’s a mockup of how it might look for a template:




          This would be a powerful way to target the right cached items. xPDO objects and result sets could be added as another checkbox, or they could be included under the third option, with reference to cache tags. Contexts could themselves be tags. There are a number of possible variations on this basic idea.
            • 22797
            • 134 Posts
            ... And I guess one more thing could be added: A checkbox that says:

            __Save these cache-clearing preferences

            ... so that users don’t have to fill them out every time, and they can override the saved preferences on a case-by-case basis if necessary