I am reprinting this older blog post on Caching in the XX Framework. It is still relevant, though I would prefer to get the basic documentation up first.
The following discussion example uses guestbook sample, on the XX framework web site. http://xxframework.org/guestbook/ListGuestbook. This non-cached page will be converted into a cached implementation.
Let’s look at the structure of the page displayed when the URL listed above is requested.
The page is divided into 5 components. This can be best illustrated by looking at the XX config file.
ListGuestbook.xml
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE xx_config SYSTEM “http://www.xxframework.org/dtd/xx_config.dtd”>
<xx_config newthread=”true“ usepool=”false“ poolcheck=”10000“>
<classes>
<class id=”3“ scope=”page“ use=”xsl“ applyxsl=”true“>
<classname>org.xxframework.control.RecordControl</classname>
<method>get</method>
<hb_classname>org.xxframework.searchfilter.Dummy</hb_classname>
<xsl_file>AddMessage.xsl</xsl_file>
<security secure=”false“>
</security>
</class>
<class id=”4“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.RecordControl</classname>
<method>get</method>
<hb_classname>org.xxframework.searchfilter.GuestbookFilter</hb_classname>
<xsl_file>ListGuestbookFilter.xsl</xsl_file>
<security secure=”false“>
</security>
</class>
<class id=”5“ scope=”page“ applyxsl=”true“ use=”xsl“ timeout=”20000“>
<classname>org.xxframework.control.RecordControl</classname>
<method>list</method>
<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>
<xsl_file>ListGuestbook.xsl</xsl_file>
<security secure=”false“>
</security>
</class>
<class id=”1“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.RecordControl</classname>
<method>list</method>
<xsl_file>mainmenu.xsl</xsl_file>
<security secure=”false“>
</security>
</class>
<class id=”2“ scope=”page“ use=”file“ applyxsl=”false“>
<endpoint>[xmlroot]/../../guestbookmenu.html</endpoint>
<security secure=”false“>
</security>
</class>
</classes>
<jsp>searchlist.jsp</jsp>
</xx_config> |
Referring the guestbook page (http://xxframework.org/guestbook/ListGuestbook), the 5 components implement the following functionality
| Class id |
Description |
| 1 |
Login Box. This box will change, based on the login state of the user |
| 2 |
Left side menu, below login area. This section doesn’t change |
| 3 |
The new message text entry in the top center |
| 4 |
The message search area in the middle center |
| 5 |
The guestbook message list. This will be the most dynamic and resource intensive component of the page. |
The other components of the page (top menu and header graphics) are included in the JSP page indicated in the config file (searchlist.jsp). Note that the JSP page can include dynamic and well as static content. In this case, the content is static.
The caching behavior is described by the “scope” attribute of the class element. The valid scope values are the following:
| Value |
Description |
| page |
No caching |
| session |
Cached at user session level |
| application |
Cached at application level, for all users |
Since all classes have page scope, no caching takes place in the ListGuestbook servlet.
If the 5 classes above, classes 2, 4, and 5 can be cached at the application level, since all users should see the same text when browsing this page. Classes 1 and 3 are user specific. Class 1 section will change from a login to a logout button depending on the logged in status of the user.
Class 3 may not be that obvious. While not really necessary, the author text box will default to the user’s user id, if logged in. If not logged in, author text box will maintain any previous value entered by that user. For a logged in user, this information is available in the XML request document. For a non-logged user, this information is maintained in the user’s session. Therefore, for classes 1 and 3, session level caching is appropriate.
To implement the caching needed, modify the scope attribute of the class element, as follows.
<classes>
<class id=”3“ scope=”session“ use=”xsl“ applyxsl=”true“>
…
</class>
<class id=”4“ scope=”application“ applyxsl=”true“ use=”xsl“>
…
</class>
<class id=”5“ scope=”application“ applyxsl=”true“ use=”xsl“>
…
</class>
<class id=”1“ scope=”session“ applyxsl=”true“ use=”xsl“>
…
</class>
<class id=”2“ scope=”application“ use=”file“ applyxsl=”false“>
…
</class>
</classes> |
The class element may also take an optional “timeout” attribute. The value of this attribute represents the time, in milliseconds, when the cache should automatically be expired.
Given a config file as above, classes 2, 4, and 5 (application level) will only be called once. Afterwards, the html values will be read from application memory (servlet context actually). Classes 3 and 5 will be called once for each user. Afterwards, the values will be read from session memory.
Leave the system in this state, however, will cause a potential problem: once generated, the pages will never change. This is not a problem for classes 2 and 4. These sections will only change when the menu for search box changes. In our case, these sections are static. If our search box contained a company pull down, for instance, the search section would need to be updated whenever a company is added or deleted.
The other page sections, however, will not remaining static. Most obvious is class 5, the message list itself. This will change whenever a message is added or deleted. Since deletion is not part of the guestbook sample, let’s consider the case when a message is added. If the cache is not updated, the new message will not show up. To fix this problem, we must look at all the use cases that could cause the cache to need to update. In the case of the guestbook application, the add message use case will invalidate the saved message list.
The add message use case is implemented by the SetMessage servlet servlet. This servlet uses the SetMessage.xml XX config file. Here is the relevant portion of that config file
SetMessage.xml
<class id=”3“ use=”xsl“ scope=”page“ applyxsl=”true“>
<classname>org.xxframework.control.RecordControl</classname>
<method>set</method>
<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>
<error_pattern><xx_error</error_pattern>
<error_jsp>main.jsp</error_jsp>
<error_xsl>reply.xsl</error_xsl>
<security secure=”true“>
<role name=”Administrator“ mode=”any“/>
<role name=”*“ mode=”add“/>
</security>
</class> |
To control caching we add a “cache_control” element.
SetMessage.xml
<class id=”3“ use=”xsl“ scope=”page“ applyxsl=”true“>
<classname>org.xxframework.control.RecordControl</classname>
<method>set</method>
<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>
<error_pattern><xx_error</error_pattern>
<error_jsp>main.jsp</error_jsp>
<error_xsl>reply.xsl</error_xsl>
<security secure=”true“>
<role name=”Administrator“ mode=”any“/>
<role name=”*“ mode=”add“/>
</security>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>5</id>
</cached_page>
</cache_control>
</class>>
</class> |
This new element states that when this class is successfully executed, clear the cached values for the indicated pages, represented by the XX config file name and class id within the config file.
In the case of the SetMessage use case, class 5 in the ListGuestbookCache config file (the message list) is cleared. The next time the ListGuestbookCache page is called, the message list will be regenerated.
The remaining two classes in the ListGuestbookCache use case are session level caches. The first, class 1 changes when the user logs in or out. Therefore, we can clear the cache for that class on the login and logout use cases. These use cases are represented by the Logon.xml and Logoff.xml file. The appropriate cache_control elements are added to these two configurations
Logon.xml
<class id=”4“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.Login</classname>
<method>get</method>
<hb_classname>org.xxframework.basetypes.User</hb_classname>
<xsl_file>Logon.xsl</xsl_file>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>1</id>
</cached_page>
</cache_control>
</class> |
Logoff.xml
<class id=”4“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.Login</classname>
<method>set</method>
<xsl_file>Logoff.xsl</xsl_file>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>1</id>
</cached_page>
</cache_control>
</class>
|
Returning to the ListGuestbookCache use case, class 3, the add message area, hasn’t yet been handled. This text box needs to change when the user adds a message, or when the user logs in and out. Therefore, we need to clear this case on user login/logout, and on add message. This can be accomplished by adding a cached_page element to the existing cache_control element. The following changes complete our requirement of clearing the cache in the appropriate situations
SetMessage.xml
<class id=”3“ use=”xsl“ scope=”page“ applyxsl=”true“>
<classname>org.xxframework.control.RecordControl</classname>
<method>set</method>
<hb_classname>org.xxframework.guestbook.entity.Message</hb_classname>
<error_pattern><xx_error</error_pattern>
<error_jsp>main.jsp</error_jsp>
<error_xsl>reply.xsl</error_xsl>
<security secure=”true“>
<role name=”Administrator“ mode=”any“/>
<role name=”*“ mode=”add“/>
</security>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>5</id>
</cached_page>
<cached_page name=”ListGuestbookCache.xml“>
<id>3</id>
</cached_page>
</cache_control>
</class> |
Logon.xml
<class id=”4“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.Login</classname>
<method>get</method>
<hb_classname>org.xxframework.basetypes.User</hb_classname>
<xsl_file>Logon.xsl</xsl_file>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>1</id>
</cached_page>
<cached_page name=”ListGuestbookCache.xml“>
<id>3</id>
</cached_page>
</cache_control>
</class> |
Logoff.xml
<class id=”4“ scope=”page“ applyxsl=”true“ use=”xsl“>
<classname>org.xxframework.control.Login</classname>
<method>set</method>
<xsl_file>Logoff.xsl</xsl_file>
<cache_control>
<cached_page name=”ListGuestbookCache.xml“>
<id>1</id>
</cached_page>
<cached_page name=”ListGuestbookCache.xml“>
<id>3</id>
</cached_page>
</cache_control>
</class>
|
Additional notes on Caching
In addition to the class id and scope, caching is specific to the parameters of a given request. For a show user user case, we would not want showuser?id=6 to use the same cache as showuser?id=7. But we would want all calls to showuser?id=6, executed by any user, to use the cached result.
Internally, XX uses the request parameters to distringuish the two so the appropriate result is returned.