OpenWGA 7.10 - OpenWGA Concepts and Features
Design and development » WebTML » FeaturesCache
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.
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.
<tml:range cachekey="KEY">
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.