Understanding the Caching Framework

(!) See MoinMoinIdeas/WikiApplicationServerPage for the current dependency system and CacheFramework for a suggestion for a replacement system.

What happens is more or less as follows when content is served:

  1. A page is identified.
  2. If an explicit action is involved (other than show), this is invoked, and it may not cause the page to be rendered depending on how its output is defined.

  3. For the default show action and for other actions invoking the normal page display, a test is made to see if the content can be cached.

  4. Where no caching is possible (see MoinMoin.Page.Page.canUseCache), formatting takes place as normal.

  5. Where caching is possible, and where a cache entry exists (see MoinMoin.Page.Page.loadCache), the stored entry is loaded and evaluated.

  6. Where no cache entry exists, an entry is created (see MoinMoin.Page.Page.makeCache) and the formatting also takes place as normal.

Within the creation of a cache entry, the page content is parsed as normal, but the formatter is provided by MoinMoin.formatter.text_python and produces Python code that is stored and then evaluated when an entry is needed. Since page content can contain dynamic things like macros and parser regions, whose output may change depending on a number of different factors besides their arguments or contents, the way such things are handled is as follows:

  1. The formatting of page content will define a collection of static dependencies, which has traditionally only included page.

  2. Upon attempting to format a macro or parser (see the macro and parser methods in MoinMoin.formatter.text_python.Formatter), the dependencies defined for such objects are retrieved (using slightly different mechanisms).

  3. If the dependencies are considered static (by belonging to the supplied list of static dependencies), the object will be formatted and its output embedded directly in the cache entry.
  4. If the dependencies are not considered static, an executable statement will be generated and incorporated into the cache entry. Thus, when the entry is evaluated, instead of a static string being obtained for the object, this statement will be obtained and executed in order to format the object at the time of evaluation.

So, where a macro or parser can provide static content for a given request, it will have its output formatted and stored in the cache entry and will not be called again to produce the same output, whereas if it provides dynamic content, it will need to be invoked and to produce output even when the surrounding page content in a cache entry is static. And since the formatting of these objects may involve the formatting of other potentially dynamic content, even if a macro or parser provides mostly static content, the above process of preparing a cache entry may end up producing executable statements within the mostly static output of a macro or parser in order to properly produce the required output when that entry is finally used.

Supporting Other Static Dependencies

Having page as the only supported static dependency means that macros and parsers generally have to disable caching or to implement it themselves. Some parsers benefit from not integrating with the page-based caching: the graphviz parser stores graph images separately as attachments so that they may be referenced and loaded by the browser, for example. But generally, if a macro or parser only depends on its arguments or contents and has no special need to treat its output as a distinct entity, it should be able to indicate a page dependency, ignore any caching considerations, and just produce output when asked to. Remember that if these objects contain other dynamic content, their cached output should still cause that content to be dynamically generated if necessary.

However, such objects may also take other information into account, such as request parameters or the active user, and since this information is not considered by the current page-based caching mechanism, it is left to such objects to determine whether they are dealing with previously cached information and to generate and retrieve such information themselves. To support request parameters in the page-based caching mechanism would require the following things:

One can envisage macros and parsers also specifying which request parameters are important to their state and thus change their output, but the API is not rich enough for this to occur: such objects can only indicate general dependencies independent of request or other contextual information.

MoinMoin: MoinDev/UnderstandingTheCachingFramework (last edited 2014-01-24 22:43:16 by PaulBoddie)