The Cache module installs the Cache tools app to flush and refresh the cache. However, please note that with Magnolia 5.3.19, the app has been deprecated and removed from the App launcher.
For more information on this see Release notes for Magnolia CORE 5.3.19.

Magnolia employs a web cache to store server responses so that future requests for the same content can be served faster. The chief benefit of using cache is a reduction in information load on the network, meaning:

  • Less bandwidth used.
  • Reduced processing.
  • Improved responsiveness.

The Magnolia cache module is based on Ehcache, an open source Java distributed cache. All cache data is stored in the filesystem. Note that the Ehcache filesystem can be local to the server or network, depending on configuration. 

Download

The Cache module is bundled with Magnolia and typically already installed. You can download it from our Nexus repository.

Installing

Cache is a Community Edition module. It is typically already installed. Launch the Configuration app and go to /modules/cache to check.

(warning) Create a backup of your system before you install a module. Uninstalling a module is not as simple as removing the .jar file. Modules add and change configurations and may change the content. Try new modules in a test environment first. A module consists of a JAR file and may include dependent JAR files. Modules are responsible for updating their own content and configurations across versions. Be sure to keep only one version of each module and its dependencies.

To install a module:

  1. Stop the application server.
  2. Copy the module JAR files into the WEB-INF/lib directory. The location of this directory depends on the application server.
    • Tomcat: /webapps/magnoliaAuthor/WEB-INF/lib
    • JBoss: /server/default/deploy/magnoliaAuthor/WEB-INF/lib
  3. Restart the server.
  4. Go to the AdminCentral URL.
  5. Start the Web update process.
  6. Click Start up Magnolia.

Repeat the steps for each author and public instance.

Uninstalling

To uninstall a module, remove the module JAR file from the /WEB-INF/lib folder and restart Magnolia.

(warning) However, this is rarely enough. Modules add and modify configuration during installation. The use of a module also changes content. Removing all of these changes is difficult without knowing the installation tasks in detail.

To test a module, use the embedded Derby database and take a backup of your repositories folder. Install the module and try it. When you are done testing, remove the module JAR and restore the repositories folder from the backup. This way you can go back to square one.

We also recommend that you segregate the development and production environments. Take regular backups for disaster recovery so you can revert to a prior state in a routine fashion.

Disabling

Although the Cache module is bundled as a separate module, it is essential to Magnolia and many other modules depend on it. Don't uninstall the Cache module. If necessary, disable caching by adding an enabled node in Configuration > /server/filters/cache and set its value to false.

Node nameValue

 server

 

 filters

 

 cache

 

 cacheConfigurationName

default

 class

info.magnolia.module.cache.filter.CacheFilter

 enabled

false

How caching works

Caching is performed by the Cache filter, which is part of the standard Magnolia filter chain . When a request arrives to the Cache filter, the filter passes it to the browser cache policy.

  • Content not modified: If a client has the latest version of content (i.e. not modified), the browser cache policy instructs the filter to respond with "304 Not Modified".
  • Modified content: If content has been modified or does not exist in the cache, the filter passes the request to the server cache policy. Server cache policy then analyses the request and replies with the expected behavior. The filter then invokes the appropriate executor. This mechanism allows you to add, remove and use executors by changing the current cache policy.
  • Content not available: If the content is not available, the filter passes the request on to Magnolia. On the return trip, the filter reads the content from the response and stores it in the cache store for future use. Flush policy is completely independent from this chain and reacts on content changes rather than content served.

Configuration

Cache configurations are defined in /modules/cache/config/configurations/. Within each configuration you can define:

  • What to cache.
  • When to flush the cache.
  • What header data to pass to browsers.
  • Specific implementations of tasks.

Node nameValue

 modules

 

 cache

 

 config

 

 configurations

 

 default

 

 uuid-key-mapping

 

 compression

 

 cacheFactory

 

To select one of the cache configurations, set the cacheConfigurationName parameter in the Cache filter. The chosen configuration is read into a JavaBean using the Node2Bean mechanism, making it dynamically available to your own module code.

Node nameValue

 server

 

 filters

 

 cache

 

 cacheConfigurationName

default

 class

info.magnolia.module.cache.filter.CacheFilter

Policy configuration

Caching behavior for each configuration is defined with policies.

  • Server cache policy: This policy defines whether the requested content should be cached or not. The decision to cache relies on voters, which are used whenever configuration values are not assigned at startup but depend on rules. Voters evaluate a rule such as "should content residing at this URL be cached" and return a positive or negative response. By default, all content on public instances is cached except the AdminCentral UI at /.magnolia. Server cache policy is configured in /modules/cache/config/configurations/default/cachePolicy. The default implementation ( Default ) checks if the content exists in the Ehcache store and requests caching if the content is not found. The alternative class, 4.5.22 Never instructs the cache not to store the generated content. Server side re-caching of no-cache requests (shift reload) are configurable and set to false by default.

    Node nameValue

     default

     

     cachePolicy

     

     voters

     

     urls

     

     deny

     

     resources

     

     class

    info.magnolia.module.cache.cachepolicy.Default

     refreshOnNoCacheRequests

    false
  • Client (browser) cache policy allows for different policies for different content types. Voters are used to define the caching rules. These policies define how long the browser may cache each content type. The time is passed to the browser in the response header. The  FixedDuration option instructs the browser to cache the content for the specified length of time in minutes. Never instructs the browser to do nothing. Client cache policy is configured in /modules/cache/config/configurations/browserCachePolicy

    Node nameValue

     default

     

     browserCachePolicy

     

     policies

     

     farFuture

     

     voters

     

     class

     info.magnolia.module.cache.browsercachepolicy.FixedDuration

     expirationMinutes

     525600

     resources

     

     dontCachePages

     

     voters

     

     class

     info.magnolia.module.cache.browsercachepolicy.Never

     stkThemeImages

     

     default

     

     voters

     

     class

     info.magnolia.module.cache.browsercachepolicy.FixedDuration

     expirationMinutes

     10

     class

    info.magnolia.module.cache.cachepolicy.Default
  • Flush policy: The Flush policy defines when to flush the cache. The default configuration observes changes (activation, import, edit) in a workspace and flushes the cache if new or modified content is detected. Cache can be flushed completely, partially or not at all. Each module can register its own flush policy (or multiple policies) and receive notification about new or modified content in each workspace. Flush policies are informed about changes in observed workspaces. The list of observed workspaces can be defined per policy under the repositories subnode of each policy.

    Node nameValue

     default

     

     flushPolicy

     

     policies

     

     flushAll

     

     repositories

     

     0

    data

     00

    dms

     01

    templates

     02

    resources

     1

    website

     category

    category

     contacts

    contacts

     dam

    dam

     class

    info.magnolia.module.cache.FlushAllListeningPolicy

     FlushByComments

     

     repositories

     

     class

    info.magnolia.module.commenting.cache.ReferencedPageFlushPolicy

     class

    info.magnolia.module.cache.DelegateFlushPolicy

Registering a workspace for flush policy

The Cache module provides a RegisterWorkspaceForCacheFlushingTask install task that custom modules can use to register their workspace in the default FlushAll policy. When registered, any cached content originating from this workspace will be flushed from the cache when a change to any content anywhere in the workspace is detected. By default the config workspace is not observed. This means that activated changes to configuration elements will not always be served in the public instance. This can be overcome by manually flushing the cache in Cache tools. Alternatively, you can add the workspace.

Executors

These are actions taken once a caching decision has been made. There are three possible actions:

  1. useCache: Retrieves the cached item from the cache and streams it to the client.
  2. store: Stores the response in the cache for future use.
  3. bypass: Skips caching. This is useful for content that cannot or should not be cached.

Executors can be configured at /modules/cache/config/configurations/executors. Each of the executors is also responsible for configuring expiration headers.

Node nameValue

 default

 

 executors

 

 bypass

 

 store

 

 useCache

 

Ehcache backend

Magnolia uses Ehcache for its back-end cache functionality. Ehcache is a robust, proven and full-featured cache product which has made it the most widely-used Java cache. Ehcache has its own configuration options that can be set in /modules/cache/config/cacheFactory/defaultCacheConfiguration.

You can use a different cache library as long as you implement Java interfaces that allow you to configure caching behavior in the Configuration app. The library can be changed by implementing Cache and  CacheFactory . A cache factory is an interface that wraps the functionality and hides the configuration mechanism of the library you choose.

ParameterDefault valueDescription
blockingTimeout 10000
Instructs Ehcache to wait the specified time in milliseconds before attempting to cache the request. Create the blockingTiemout property in the tree at the same level where the EhCacheFactory class is defined, not inside the defaultCacheConfiguration node.
diskExpiryThreadIntervalSeconds120Number of seconds between runs of the disk expiry thread.
diskPersistenttrueDetermines if disk store persists between restarts of the Virtual Machine.
diskSpoolBufferSizeMB30Size to allocate to DiskStore for a spool buffer. Writes are made to this area and then asynchronously written to disk. Default: 30MB. Each spool buffer is used only by its cache. If OutOfMemory errors, you may need to lower this value. To improve DiskStore performance consider increasing it. Trace level logging in the DiskStore will show if put back ups are occurring.
eternaltrueIf elements are set to eternal, timeouts are ignored and the element is never expired.
maxElementsInMemory10000Sets maximum number of objects that will be created in memory. 0 = no limit
maxElementsOnDisk10000000Sets maximum number of objects maintained in the DiskStore. The default value of zero means unlimited.
memoryStoreEvictionPolicyLRU

Policy is enforced upon reaching the maxElementsInMemory limit. Available policies:

  • Least Recently Used (specified as LRU)
  • First In First Out (specified as FIFO)
  • Less Frequently Used (specified as LFU)
overflowToDisktruePermits elements to overflow to disk when the memory store has reached the maxInMemory limit.
timeToIdleSeconds0Optional attribute. Sets max idle time between accesses for an element before it expires. Only used if the element is not eternal. A value of 0 means that an Element can idle indefinitely.
timeToLiveSeconds0Sets lifespan for an element. Only used if the element is not eternal. Optional attribute. A value of 0 means an Element can live for infinity

Compression

Compression is a simple and effective way to save bandwidth and speed up your site. It is a common practice used by Google and Yahoo! for example. (How to Optimize Your Site with GZIP Compression is a great general introduction to the topic.) Compression is performed in the gzip filter, configured in /server/filters/gzip}. When a client requests a resource such as index.html, Magnolia delivers it zipped. A typical HTML page is compressed to 20% of its original size. So if your page is 100 kB uncompressed, it is 20 kB compressed. To improve performance further, zipped content is streamed from the repository to the client rather than read into memory first.

Configuring

You can configure which content types to compress. By default the gzip filter bypasses compression for HTML, JavaScript and CSS because they are explicitly selected for compression in the Cache module configuration. These types can be compressed efficiently because they are text. The decision to compress a particular content type is made with voters. Voters are used whenever configuration values are not assigned at startup but depend on rules instead. In the Cache module configuration there are three voting rules based on content type:

  • text/html: HTML.
  • application/x-javascript: JavaScript.
  • text/css: Cascading Style Sheets.

Node nameValue

 cache

 

 config

 

 configurations

 

 compression

 

 voters

 

 contentType

 

 allowed

 

 1

text/html

 2

application/x-javascript

 3

text/css

 class

info.magnolia.voting.voters.ResponseContentTypeVoter

To add more content types, such as XML, create a numbered property under allowed. Use the Internet media type (MIME type) as value. Here are some common media types:

  • application/xhtml+xml: XHTM L.
  • text/csv: Comma-separated value.
  • text/plain: Textual data.
  • text/xml: Extensible Markup Languag.
  • application/pdf: Portable Document Format.

As a rule, compressing the HTML, JavaScript and CSS is sufficient; it is not necessary to compress binary content such as images. During the process, the browser sends a header telling the server that it accepts compressed content: Accept-Encoding: gzip. Note that Magnolia does not cache big binaries.

Internet Explorer 6

Note that while all modern browsers support compression, some older browsers do not, notably Internet Explorer 6 before Service Pack 2. To get around this, Magnolia uses a userAgent voter that rejects compression and delivers uncompressed content if the browser identifies itself as IE6 in the User-Agent field in request headers.

Node nameValue

 compression

 

 voters

 

 contentType

 

 userAgent

 

 rejected

 

 00

.*MSIE 6\.0.*

 class

info.magnolia.voting.voters.UserAgentVoter

Testing compression

To test your compression configuration, use a tool such as Web-Sniffer that allows you to change the Accept, Encoding and User-Agent sent headers easily. Here's what the headers look like when the Magnolia demo site home page is submitted to the sniffer.

Request header:

GET /demo-project.html HTTP/1.1 Host: demopublic.magnolia-cms.com 
Connection: close User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; 
de; rv:1.9) Gecko/2008052906 Firefox/3.0 Accept-Encoding: gzip 
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7 Cache-Control: no 
Accept-Language: de,en;q=0.7,en-us;q=0.3 Referer: http://web-sniffer.net

Response header:

Status: HTTP/1.1 200 OK Date: Fri, 23 Jul 2010 07:45:10 GMT Server: 
Apache/2.2.9 X-Magnolia-Registration: Registered Cache-Control: 
max-age=900 Last-Modified: Thu, 01 Jul 2010 14:03:12 GMT 
Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 3852 
Connection: close Content-Type: text/html;charset=UTF-8

Advanced strategies

In the Enterprise Edition advanced caching strategies are available in a separate Advanced Cache module .

Commands

Cache related commands are in the cache catalog:

  • flushAll: Completely flushes all caches that are configured in /modules/cache/config/configurations/default/flushPolicy/policies/flushAll/repositories. Note that the imaging workspace is not included in the flush by default.
  • flushByUUID: Completely flushes all entries related to a given UUID from all available caches. This command expects repository and uuid as parameters.
  • flushNamedCache: Completely flushes a cache by name. Default cache names are default and uuid-key-mapping.

Tools

(warning) With Magnolia 5.3.19, the app has been deprecated and removed from the App launcher. For more information see Release notes for Magnolia CORE 5.3.19.

The Cache tools app provides the following operations:

  • Caches information: Tells you the number of elements currently in the cache.

  • Flush from caches by UUID: Allows you to flush a single item by specifying the UUID and repository.

  • Flush a cache by name: Allows you to flush a named cache.

  • Flush all caches: Flushes all cached elements.

The Cache tools page is installed as part of the Cache module.

Cached URLs

By default, the following URLs are cached:

  • On public instance everything except /.magnolia/* which is AdminCentral.
  • On author instance all static resources /.resources/* if magnolia.develop property is set to false.

Cache strategies

The system caches resources such as JavaScript files and CSS files on the author instance by default to make authoring more responsive. Disable this behavior when developing. Set the magnolia.develop property to true in the default magnolia.properties file. For more complex configurations, you need to adjust the configuration under the /config/configuration/default/cachePolicy/voters node

Flushing the cache

  • Shut down Magnolia, delete the cache directory and restart.
  • Enable Java Management Extensions (JMX). (It is enabled by default on some application servers.) Connect to the server using jconsole or use your server's own JMX administration interface if provided. Locate the net.sf.ehcache.CacheManager bean and invoke the flush() operation of the default instance of the cache.
  • Any activation from author instance to public automatically flushes the public cache.
  • Use the tools in the Tools > Cache tools app.

Note that the cache is not aware of the web application context; if you are changing the context of a previously deployed application, you need to flush the cache to make sure served pages do not contain absolute links still pointing to old context path.

Excluding content from cache

There are various reasons why you may wish to exclude content from cache. For example, you may have components that query an external data source dynamically. The rendered HTML changes even if the content of the Magnolia page has not changed. When we say cached content we mean the rendered output generated by Magnolia itself, the actual content of the page. When you exclude a page from cache you tell Magnolia that it should re-render that content every time the page is requested by a user.

Configuring an exclusion

The first option for excluding content from cache is to configure an exclusion in the cache policy. The example below excludes all pages whose URL starts with /.magnolia. This means that AdminCentral pages are not cached.

Node nameValue

 modules

 

 cache

 

 config

 

 configurations

 

 default

 

 cachePolicy

 

 voters

 

 urls

 

 includes

 

 exludes

 

 dotMagnolia

 

 class

info.magnolia.voting.voters.URIStartsWithVoter

 pattern

/.magnolia

 not

true

 level

1

Implementing a custom cache policy

To implement a custom cache policy, implement the  CachePolicy interface and override the methods you wish to customize. The default policy:

...determines if a requested page should be cached, retrieved from the cache or not cached at all. It is called for every request and takes care of any expiration policy, that is if the page should be re-cached. The CacheFilter (or any other client component) can determine its behavior based on the return CachePolicyResult, which holds both the behavior to take and the cache key to use when appropriate.

Configure your custom cache policy class in /modules/cache/config/configuration/default/cachepolicy.

Cache header negotiation

Cache header negotiation is a mechanism that allows templates and components to influence whether the content should be cached and for how long. This mechanism can be used when it is too late to configure an exclude, but you do not wish for a page to be cached. Excludes are typically configured before it is clear what kinds of pages editors will add and what kind of content those pages will have. Cache header negotiation allows page components to influence whether the page should be cached. You can use cache header negotiation for:

  • Live, dynamic data: A component that display dynamic data can indicate that the page the component is, or should be, cached only for a short duration: 5 minutes, 1 minute etc.
  • Personalized content. Components that display personalized content can indicate that the page should not be cached at all.
  • Error resolution: If a component fails to read data from an external source and outputs a message to say there is a problem, you may not want to cache the error message, at least not for long. Instead, it is better if the component makes another attempt at getting the data when the next visitor requests the page. When you configure caching in many components, remember that the strictest criteria wins. If a page has a component that indicates that content should not be cached, the page will not be cached regardless of what components say. For example, if the live data and personalization components mentioned above are added on the same page, the page won't be cached at all. A template can influence the decision in the same way. A template might want to cache the page for 10 minutes because the page displays real-time weather updates. If a component on the page wants to be cached for a maximum of 15 minutes, the template's instructions win because they are stricter. The page is cached for 10 minutes.

Other options

The following options are not best practices but they may help you during testing. Don't use them as a long-term production strategy.

  • Dummy URL parameter: The simplest way to exclude content is to link to the relevant page with a dummy query parameter in the URL such as http://www.example.com?a=1 . A more subtle solution is to add bypass to the cache filter. This ensures that no cache filter is executed on particular URLs.
  • Deny URLs in cache policy: To exclude a URL from caching, add the URL to the deny list of the cachePolicy. Entries on the deny list are not cached by Magnolia but are taken through the entire filter chain, meaning that other policies such as BrowserCachePolicy can still be applied. In effect this solution, 'switches off' caching for the URL in question.
  • Regular cache flush: Flush a page from the cache at regular intervals. This involves reconfiguring the underlying cache engine (Ehcache).

Setting cache headers

Cache header negotiation uses standard cache response headers. Cache needs to be enabled for the site or cache headers have no effect on the server side cache. The mechanism is built into the Cache module and requires no extra modules. Cache header negotiation is being introduced to Magnolia in two phases:

In code

In code, developers set the cache headers in the rendering model of a component or a template. This is the current implementation.

Example 1: Setting a cache header in Java code, snippet from AbstractFormModel .

MgnlContext.getWebContext().getResponse().setHeader("Cache-Control", "no-cache");

Example 2: Setting a cache header in a JSP template script.

<% response.setHeader("Cache-Control", "no-cache"); %>

Setting cache attributes in code

Available in version 5.3.2 or higher.

In memory threshold

This threshold is used to determine if a resource should be cached or not according to its size. The default value of 500K was not selected randomly, but as a result of testing that shown 98% of resources were served as fast from memory as from the repo when exceeding this value. This is mainly due to the fact that transport of such amount of data offsets time needed for accessing the repository. 

You can still change this value programatically, e.g. in your custom renderer which does time-consuming operations:

MgnlContext.getWebContext().getRequest().setAttribute(CacheResponseWrapper.ATTRIBUTE_IN_MEMORY_THRESHOLD, CacheResponseWrapper.DEFAULT_THRESHOLD * 2);

You need to set this attribute before anything is written to the output.

#trackbackRdf ($trackbackUtils.getContentIdentifier($page) $page.title $trackbackUtils.getPingUrl($page))