OpenWGA 7.9 - OpenWGA Concepts and Features

Design and development » WebTML » Features

Cache

The WebTML cache can be used to cache the rendering results of a specific WebTML code range. It stores the rendered contents of a range tag as string and reuses it in appropriate situations without recalculating. This can be useful if you have WebTML/TMLScript code that runs too long or creates too much traffic on backend databases to be rendered on each request

A range that should be cached in WebTML cache can be simply defined by surrounding it with a <tml:range> that contains attribute cachekey. For a range tag using the WebTML cache the id attribute is mandatory.

<tml:range id="heavylifting" cachekey="AREA">

  <tml:siblings context="root">

    ...

  </tml:siblings>

</tml:range>

The attribute "cachekey" defines a TML script expression, which is executed each time the range tag is rendered. The expression result is used as a "cache key" by which the cache entry is determined that is used by the range tag. That way the range tag may store and retrieve differing cache entries depending on the current environment.

You can also leave the contents of the cachekey attribute entry if the range tag should always use the same entry. In that case WebTML will always use an empty string as cache key.

How the WebTML cache works

If a range tag is defined with an attribute "cachekey", OpenWGA first tries to find an entry for this key in the WebTML cache. It will only find entries for the current WebTML tag, based on its id attribute (which is mandatory when using WebTML cache). If no entry is present the WebTML code contained in the range tag is rendered and put out as usual, but after this rendering the produced code will be stored to the WebTML cache under the previously calculated key.

When an entry already exists in the WebTML cache for the given key then it is first tested if the cache was created for a previous database state (unless this has been disabled using attribute cacheupdate="never"). To judge this each cache entry not only contains the cached code but also the revision state of the database that was in the context of the range tag as at the time that the code was rendered. If it is different from the current revision state of the database then WebTML will not use this cache entry. Instead it will re-render the WebTML contents of the range tag - just as if there was no entry present - and again store the result into cache with the current revision state.

But ff the cache revision is the same as the current revision then WebTML is allowed to use the cache directly. The WebTML contents of the range tag is not rendered. Instead the text that is stored in the cache is directly put out to the client without any WebTML/TMLScript processing.

Choosing a cache key expression

In many situations usage of a dynamic cache key is not necessary and the "cachekey" attribute may be left empty. This is the case if the following is true: The result that is rendered by the contents of the range tag is/should be exactly the same for all potential viewers of the resulting page in any situation.

In some situations however the data that is rendered by WebTML is only appropriate for special users or situations.  For example:

A WebTML navigator should be cached and uses an empty cache key. It may contain documents that are read protected for special users, so they should not be allowed to see them. Now imagine there is a document "A" that may be only read by user "Yuki". Now user "Yuki" is by chance the first to render that page that contains the cached WebTML navigator. The range tag determines that there is no caching entry yet. So the contents of the range tag is rendered under the rights of user "Yuki" and the generated navigator contains read-protected document A.  The resulting HTML code of the navigator is stored to cache, containing information about document "A".

Now user "Kinga" renders the same page. She is not allowed to see document "A", but as the cache is filled now she is presented the navigator code that was rendered under the rights of user "Yuki", which clearly is a problem.

To prevent these situations the cache key expression allows you to dynamically calculate keys for different cache entries, so each user is only presented the data that he should see.

The simplest way to have a WebTML cache that stores cache entries for each individual user is to calculate the cache key based on the user name. That way, each user has a separate cache key and therefor also a separate cache entry:

<tml:range cachekey="meta('db', 'username')">

With such a cache key expression WebTML would store and retrieve differing cache entries for the users "Yuki" and "Kinga". The downside of this is that the cache now needs to be calculated for each user that renders the range tag, so performance improvement is not that big but may still be big enough.

Not all situations with dynamic cache keys address security problems. Imagine a WebTML range that calculates its results based on the current context document, so the results would - and must - be different for each context. Address this by calculating the cache key based on the content key of the current context:

<tml:range cachekey="KEY">

Of course you can also calculate caches by a combination of conditions, just by concatenating the results of individual TMLScript functionalities. Many other conditions can be thought of to calculate a cache entry based on numerous environment propierties like, server host, name of user profile, area name etc.

More functionalities

If your rendered cache entries are only valid for a certain amount of time and should be re-rendered after it then you may want to define a latency for them using attribute cachelatency. It takes a number of minutes. If the rendering of the cache is older than the minutes given here then it is considered stale and will be re-rendered.

WebTML Cache and Server Memory

WebTML cache entries are stored to the memory of the OpenWGA server and may therefor influence the resource usage of it. However the number of allowed cache entries is reduced to 10.000 entries for the whole OpenWGA runtime. After reaching this number the oldest entries will be dropped on the rendering of newer entries. But as the size of WebTML cache entries differs by the size of the cached code this is no absolutely safe way to prevent resource exhaustion. Therefor care should be taken not to create too much and large cache entries for the memory that is available to OpenWGA.

If a resource problem seems related to WebTML cache usage then the OpenWGA administrator may create a  "WebTML cache dump" via OpenWGA admin client (Menu "Runtime" > Tab "Status" > Button "WebTML cache dump". This is a file that lists all stored caches with their real sizes in bytes. That way it should be easy to identify caches that are too large.