We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 22295
    • 153 Posts
    Reading through:
    http://svn.modxcms.com/docs/display/revolution/Caching
    and looking at your core code (various processors that run this).
    Everywhere I see you clear all the cache.

    In my case - it is not efficient, as new content will be created very often by all of the system’s users. Then - ALL the site’s cache will be cleared for no reason.

    Is it possible to clearCache a specific page AND it’s elements?
    Something like this code wouldn’t work. The page’s cache file is delete, but because i don’t delete also "context.cache.php", the page’s inner-snippets are returned from cached (whether via direct snippet call [[ ]], or ->runSnippet().


        $cacheManager->clearCache(array (
                "{$resource->context_key}/resources/".$_POST['parent'].".cache.php"
            ),
            array(
                'objects' => '*',
                'publishing' => true
            )
        );


    in the above example - user creates a sub-document under his profile (also a modDocument).
    the profile page has ditto of his sub-documents which is persistantly cached (this is why the $_POST[’parent’])
    So i want to clear the parent page’s cache after document post. (the same will be for other actions, edit, delete, etc...)

    Thanks in advance
      • 28042 ☆ A M B ☆
      • 24,524 Posts
      What about menus and other dynamic content dependent document IDs and content? If you don’t clear all the cache, documents could be loaded with stale dynamic data.
        Studying MODX in the desert - http://sottwell.com
        Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
        Join the Slack Community - http://modx.org
        • 22303 MODX Staff
        • 10,725 Posts
        Susan has good points overall, though advanced options for cache clearing is something that has been discussed, so you can clear just a single page in the cache. This code should do it:
        $modx->cacheManager->clearCache(array($resource->getCacheKey() . '.cache.php'));

        Elements are cached per page, so clearing the page cache will clear any element cache. Not sure what you mean by the page’s inner-snippets are returned from cache, because if the page’s cache file is gone, so is the corresponding element cache. What will not change is the map of resources and their URLs that are contained in the context (which is in the context.cache.php file). IOW, a snippet to create a menu will not be aware of a change to the alias, or any new documents that may have been added without clearing the context cache.
          • 22295
          • 153 Posts
          Thanks for both replies.

          IOW, a snippet to create a menu will not be aware of a change to the alias, or any new documents that may have been added without clearing the context cache.

          Exactly.
          practically, this means that whenever a user post content (resource) in HIS profile, the whole site’s cache needs to be purged in order to refresh the map (clearing the context cache).

          In a collaborative web site, where posting is what people do.. this makes no sense.

          Question - clearing the specific page cache + context.cache vs. clear all the cache. makes sense? as then only the resource map would be rebuilt, but the other pages will stay cached.
          AFAIK, this shouldn’t lead to any cache inconsistency, and looks like it’ll save some CPU (again - just imagine this site is about posting..)

          In the first phase (500 users * 5-10 posts each, mild activity) - i doubt if the (lack of) cache would present a problem, but it would be nice to be able to selectively refresh a fragment of the context.cache (I am sure you agree it totally makes sense).



          (un)related - I am now examining getCacheManager() for my custom snippets to minimize db queries.
          Working with a complex structure (multiple tables define a user) and xpdo’s Graph objects is heavy! seems like if I brake some fragments and use the above to create my own custom cache files, mainly to cache member details - i could minimize the need to use graph objects (getObjectGraph/getCollectionGraph).

          As an interesting built-in alternative -
          I saw this "xPDO Object and Database Result Set Caching" here: http://svn.modxcms.com/docs/display/revolution/Caching

          and "Enable database cahce (cache_db)" in the "system settings"
          and this: xPDOMemCache
          and the $cacheFlag in xpdo’s Graph methods (I would put a BIG number here?)
          and ofcourse this: xpdo’s fromCache method.

          As far as I understand - these can assist the performance (in my case) even more the above (post caching).
          I’m still not 100% clear on how it all interacts, but that should be resolved in the next days.
          Psuedo-code or any guideline would be greatly appriciated.

          Any specific reason why cache_db is disabled by default?
          (seems like this is a hidden-power waiting to be explored under revo)

          Thank.
            • 22303 MODX Staff
            • 10,725 Posts
            Quote from: oori at Dec 16, 2009, 09:53 AM

            IOW, a snippet to create a menu will not be aware of a change to the alias, or any new documents that may have been added without clearing the context cache.

            Exactly.
            practically, this means that whenever a user post content (resource) in HIS profile, the whole site’s cache needs to be purged in order to refresh the map (clearing the context cache).

            In a collaborative web site, where posting is what people do.. this makes no sense.
            IMO, collaborative web applications like you describe should be created using a single Resource serving as a view into the highly dynamic content being posted. Any navigation for these posts would similarly be dynamic and not be related to the main web site cache anyway. However, as an alternative to avoid creating a custom web application and data structure for supporting it, you can partition the collaborative portion of the site into a separate context so that posting changes to/adding Resources only affects that context’s cache.

            Quote from: oori at Dec 16, 2009, 09:53 AM

            Question - clearing the specific page cache + context.cache vs. clear all the cache. makes sense? as then only the resource map would be rebuilt, but the other pages will stay cached.
            AFAIK, this shouldn’t lead to any cache inconsistency, and looks like it’ll save some CPU (again - just imagine this site is about posting..)

            In the first phase (500 users * 5-10 posts each, mild activity) - i doubt if the (lack of) cache would present a problem, but it would be nice to be able to selectively refresh a fragment of the context.cache (I am sure you agree it totally makes sense).
            If you don’t clear the other pages, they will not be aware of the changes to the URL structure of the site; same problem regarding navigation components. That said, we could provide this option when creating/editing a Resource, but you’d have to be aware that any navigation component would have to be uncached.

            Quote from: oori at Dec 16, 2009, 09:53 AM

            (un)related - I am now examining getCacheManager() for my custom snippets to minimize db queries.
            Working with a complex structure (multiple tables define a user) and xpdo’s Graph objects is heavy! seems like if I brake some fragments and use the above to create my own custom cache files, mainly to cache member details - i could minimize the need to use graph objects (getObjectGraph/getCollectionGraph).

            As an interesting built-in alternative -
            I saw this "xPDO Object and Database Result Set Caching" here: http://svn.modxcms.com/docs/display/revolution/Caching

            and "Enable database cahce (cache_db)" in the "system settings"
            and this: xPDOMemCache
            and the $cacheFlag in xpdo’s Graph methods (I would put a BIG number here?)
            and ofcourse this: xpdo’s fromCache method.

            As far as I understand - these can assist the performance (in my case) even more the above (post caching).
            I’m still not 100% clear on how it all interacts, but that should be resolved in the next days.
            Psuedo-code or any guideline would be greatly appriciated.

            Any specific reason why cache_db is disabled by default?
            (seems like this is a hidden-power waiting to be explored under revo)
            Working with graph objects is actually less heavy than the alternative; these use simple joins and can greatly reduce database load when used appropriately. Combined with lazy loading techniques, you can also reduce memory consumption as appropriate (i.e. if you are only using a few fields from an object graph).

            cacahe_db is disabled by default because it’s not appropriate in all environments and needs additional testing. But yes, caching database result sets by enabling cache_db will greatly (or even completely) decrease the load on your database, though with the default file-based cache handler, it increases file I/O. The default behavior when cache_db is on is to cache these result sets indefinitely (i.e. until data in the result set changes), though you can configure this to be timed.

            Now if you have an environment with memcached available, you can configure/use the xPDOMemCache cache handler and avoid the file I/O issue on database result set caching, or any part of the MODx cache system (i.e. each part of the cache can be configured to use these built-in handlers or one you provide yourself). And it even works with get*Graph() methods.

            There are tradeoffs with any caching approach here (i.e. since memcached does not support clearing groups of cache objects, it must flush an entire section of the cache when changes are made, vs. the file-based handler which does support clearing groups stored hierarchically). We’ll be more fully documenting the various caching options and their various benefits as we approach GA release. In the meantime, feel free to continue to ask questions and we’ll help you better understand your options here without having to circumvent the core code.
              • 22295
              • 153 Posts
              Thanks for the elaborated reply.



              IMO, collaborative web applications like you describe should be created using a single Resource serving as a view into the highly dynamic content being posted. Any navigation for these posts would similarly be dynamic and not be related to the main web site cache anyway.

              You mean like quip, for example. where a comment is not a resource.
              In my case, the user’s post is equivalent to a blog post. there’s no one blog in the site, but hundreds of small-blogs.. each user runs his posts, children of his profile document.
              I chose to implement this as a standard resource (modDocument **) simply because it fitted by design. I could rapidly reuse many of the existing functionality in modx (tv(!!), acl, pre-built processors, moderation via manager ui, etc...). This client already has some modx’s running, they are used to the modx-management logic.

              Now - as far as I see, the only drawback is this caching issue, but even though - I would have chosen the existing method over again (unless I’m missing another drawback that is waiting around the corner?!)

              ** (unrelated note) modDocument - what’s the story with this, why didn’t you fully switch to modResource only in revo? in the schema i see it’s (almost) marked for removal, and it’S there to maintain evo-compatibility. but - in all around the core+extras, I see you always work with modDocument class - so i understand you decided to stay with that?




              If you don’t clear the other pages, they will not be aware of the changes to the URL structure of the site; same problem regarding navigation components. That said, we could provide this option when creating/editing a Resource, but you’d have to be aware that any navigation component would have to be uncached.

              Wait - that’s good news! in my case, the "other pages" don’t need to be aware of this change, because the navigation component that expose the user’s post is ONLY in the user’s profile page.
              A visitor can get to the member’s blog post only from the member’s profile page (well, besides this data aggregated through the activity stream components - but that’s gets it’s resource listing from a custom activity table - so it’s out of this loop).

              So i repeat my earlier question, is it ok with modx if i only clear the cache by deleting the page + context.cache? in terms of performance, it seems way better.

              * can you clarify the term "navigation component"? which methods work with context cache, anything that looks at structure?


              cache_db
              Looks interesting, I want to test this, but i got this error, once I enabled this setting, I lost manager + all front-end pages:
              Fatal error: Cannot access protected property xPDOQuery_mysql::$sql in C:\xampp\htdocs_81\core\xpdo\xpdo.class.php on line 1460


              (related with fromCache function)
              I’m running svn 6192.


              for other as reference - you can recover from this kind of event by:
              a. changing the setting in the db:
              UPDATE modx_system_settings SET `value`='0' WHERE `key`='cache_db'
              b. delete this file: core/cache/config.cache.php
              



              Thanks again for the very helpful support!


                • 22295
                • 153 Posts
                Addendum
                I (used to) ride on your manager processors, but I just realized that you clear all cache the end of the operation.. for example - resource delete, create, etc...

                Ok, so this, added with a parallel forum post regarding permissions (document owner permission) means I should just call my own processors - that’ll be simpler.. (they are basically 80% copy and paste of yours..)

                Good to know...
                  • 32699 ☆ A M B ☆
                  • 427 Posts
                  This may simply be a design issue on the front end -- but I completely agree with needing the ability to cache and decache. As i never quite got Evolution caching working reliably I just ignored it and used my own content attached to $_SESSION vars and ajax responders connected to php snippets in modX.

                  I build dynamic sites, which largely involve an ajax single click to a jquery linked image to produce extensive results in the back end -- no one knows about. They only see a simple refresh of a division on the page -- just enough to let them see something changed. Too little and they miss it -- too much and they are distracted or confused.

                  After upgrading to beta 5 on my site and here on the testing server today I will be jumping into working with database tables of my own with xPdo on top of modX and then work on getting an ajax interaction going.
                    Get your copy of MODX Revolution Building the Web Your Way http://www.sanitypress.com/books/modx-revolution-building-the-web-your-way.html

                    Check out my MODX || xPDO resources here: http://www.shawnwilkerson.com
                    • 22295
                    • 153 Posts
                    @wshawn, thanks for the reply - but the $_session method doesn’t seem to fit my needs.
                    @OpenGeek, I would be grateful for an answer to my post #6
                    (especially regarding enabling db_cache..)


                    And to focus my question even more - I have a function which is similiar to getUserInfo() only much more complex query going on (but still - single getObjectGraph query with schema def’ made out of a couple of tables and related sub-tables)
                    (btw- i just added to jira: MODX-1519)

                    This functionality is used A LOT across the site. so - not only for the current user, but users listing, activity streams, blackboard, likes, relationships (contacts), etc.. all these things are displayed with the source user’s details (some more some less, but still - never only username...)

                    On the other hand - unlike the content, this data (user’s details) is mostly static and would undoubtly enjoy xpdo/db caching!


                    from the various caching methods available, which would you recommend?
                    How does xpdo’s getObjectGraph $cacheFlag param play along the db caching technics you mentioned? is it dependent on db_cache or unrelated? do I need to explicitly use fromCache?

                    Sorry for the "scattered questions" - but xpdo’s caching is still not clear for me (and i couldn’t test cache_db)
                    I think I’ll try to profile this with xdebug to get more details on what’s going on..


                    Final comment - as I’m working a lot on revolution these days building a social network application - I must end the post with the usual - "wow" this is a great piece of framework! although the beginning is tricky (well, still in beta..) - once you dive in and get the logic - adding add-ons, ajaxing it all (hail the processors!), and extending functionality (even permission wink) is extremely fast and straight forward!

                    Thanks again for open sourcing it all.
                      • 22303 MODX Staff
                      • 10,725 Posts
                      Quote from: oori at Dec 18, 2009, 11:12 PM

                      @OpenGeek, I would be grateful for an answer to my post #6
                      (especially regarding enabling db_cache..)
                      This is fixed in branches/2.0 @ revision 6235; it was an error in xPDO 2.0 since the php 5 only changes were introduced. Let me know if you find any other problems with the cache_db functionality.

                      Quote from: oori at Dec 18, 2009, 11:12 PM

                      from the various caching methods available, which would you recommend?
                      How does xpdo’s getObjectGraph $cacheFlag param play along the db caching technics you mentioned? is it dependent on db_cache or unrelated? do I need to explicitly use fromCache?
                      Now that it’s fixed, the cache_db functionality should work fine. And you don’t need to specify the $cacheFlag; this can be controlled system wide using the cache_db_expires system setting (which by default is 0, which means it never expires unless the database row is changed).