Tuesday, November 17, 2009

Expiration and validation caching

Portlet 2.0 specification makes it optional for portlet containers to implement these features. Any portal will eventually need these features to cut down the load time of portal pages. In this blog entry, I will try to explain the concepts behind expiration and validation caching and what to do in case these features are not supported by your portlet container.
Expiration caching
Expiration caching refers to the caching strategy wherein the portlet container caches portlet content only for a specified duration of time. You can specify the duration declaratively in portlet deployment descriptor using element.
Validation caching
The least understood and used, validation caching strategy extends the concept of expiration caching. It is based on a validation token, which is set by portlet developer when generating the portlet content in the render method of the portlet. This is done by using setETag method of CacheControl object. You'll normally set a validation token as something which can help you validate the cached content when the duration for the cached content expires. Lets say you set the expiration time for the cache as 100 seconds.

Lets assume that we are using number of records in the database as a value for the ETAG. Which means that if we see that the number of records has changed in the database then the cached content is considered expired. Lets assume that we set the value of ETAG as 10 previously because at that time the number of records in the database was 10.

The following things will happen when the cache expires:
1- As the cache has expired, portlet container will send the render request to the portlet. Remember that portlet container doesn't send render request to a portlet if the cache has not expired.
2- The portlet's render method will now check the value of ETAG (that we set when the first time our portlet generated the content). It is the responsibility of the portlet container to provide the previously set value of ETAG using getETag method of RenderRequest object.
3. In the render method we get fresh record count from the database. If this record count = 10, which is the same as the previously stored value of ETAG then it means that the cache is still valid and can be reused. At this time we instruct the portlet container to use the already cached content by calling setUseCachedContent(true) method of CacheControl object.
4. If the fresh record count from database is <> 10 then it means that some records has been deleted or added to the database and therefore the cached content is no longer valid. At this time you'll fetch fresh set of records from the database and generate the content. You'll also set a new value for the ETAG so that when the next render request is received by the portlet then it can validate against the value of ETAG to decide whether to use the cached content or get fresh records from the database. When generating fresh content or instructing portlet container to use the already cached content, you must set the expiration time for the content by using setExpirationTime of CacheControl object. This ensures that the next render request is received by the portlet only after the currently set content is expired.

The use of record count as a validation token is not recommended if your database data can also get updated, where the number of records won't change but your cache actually becomes invalid. In real projects, you'll need to figure out what should act as a validation token for your portlet. It could be last modified timestamp of a record (assuming that your portlet shows one record) or anything else that can validate if the cached data is no longer valid.

In the next entry i will write about public / private cache scopes in caching.

No comments:

Post a Comment