Using the Cache servlet bean can save a lot of time when you use it properly. When used incorrectly, it can slow rendering of a Java Sever Page and even cause the page to display incorrect data. It is important to understand how Cache works in order to avoid mistakes that can slow your pages or make them wrong.

(If you are not familiar with Cache, you may want to read more about it in Appendix B: ATG Servlet Beans of the ATG Page Developer's Guide.

Let’s examine an example where Cache actually slows down your web site. The following example uses Cache on a page called hello.jsp:

<dsp:droplet name="Cache">
  <dsp:oparam name="empty">
    Hello world!
  </dsp:oparam>
</dsp:droplet>

Cache stores the value “Hello world!” in its cache so that future retrievals can come from that cache. This is not a good place to use Cache from an efficiency point of view. Without Cache, the Java code generated to print a static string is very fast and simple. The use of Cache in this example causes an unnecessary servlet invocation and the unnecessary storage of more bytes. The Cache servlet bean is only useful when you are caching dynamic content.

Here is another example in which Cache causes incorrect results. The dynamic pricing engine is among the most “costly” pieces of functionality used in the Pioneer Cycling Store JSP code because it calculates pricing on the fly and can run slowly. Determining a dynamic price for each SKU personalized for each user takes many more computation resources than finding and displaying static prices. It is dynamic, so one way to make it run faster is to cache it. Every SKU has a different price, so you can use the SKU ID as a key into the cache.

<dsp:droplet name="/atg/dynamo/droplet/Cache">
            <dsp:param name="key" param="Sku.repositoryId "/>
            <dsp:oparam name="output">

<dsp:droplet name="/atg/commerce/pricing/PriceItem">
  <dsp:param name="item" param="Sku"/>
  <dsp:param name="elementName" value="PricedSku"/>

  <dsp:oparam name="output">
    <dsp:droplet name="/atg/dynamo/droplet/Compare">
      <dsp:param name="obj1" param="PricedSku.priceInfo.ListPrice"/>
      <dsp:param name="obj2" param="PricedSku.priceInfo.amount"/>

      <%/*ListPrice is greater, so display it first in strikout mode: */%>
      <dsp:oparam name="greaterthan">
        <span class="strikeout">
          <dsp:valueof converter="currency"
               param="PricedSku.priceInfo.ListPrice"/>
        </span>
      </dsp:oparam>
    </dsp:droplet>

   <%/*Display their price: */%>
   <dsp:valueof converter="currency" param="PricedSku.priceInfo.amount"/>
  </dsp:oparam>
</dsp:droplet> <%/*PriceItem droplet*/%>

  </dsp:oparam>
</dsp:droplet>

In this code example, Cache caches a string representing the formatted price of the SKU, for example, “$42”. It is much faster to let Cache render the string “$42” than to let the PriceItem servlet bean calculate a price, so caching this string seems like a good idea. However, PriceItem calculates personalized prices, so if a user has a promotion for 20% off everything and he is the first to invoke the cached PriceItem for SKU123, then his price is cached and even users who don’t have the 20% off promotion see that price.

A solution might be to key the cache a combination of the profile ID and the SKU ID. The problem remains that the string manipulation needed to construct a key out of those two pieces of data would cost time and that the hit ratio on such a cache would likely be so low as to render the cache useless. Worst of all, if the user is granted a promotion before the cache times out, the user sees the incorrect price.

Another situation to consider is caching content that contains links. In order to perform session tracking, the session ID must be carried by every HTTP request either in a cookie or in the URL link, and inserted by on-the-fly link rewriting. Cache cannot cache content that needs to have link rewriting performed on it. If you choose to use Cache to cache content that contains links and if a good portion of your user population does not accept session cookies, then invoking Cache on content that contains link wastes time.

We have now explored in detail some situations where you should not use the Cache servlet bean:

You should use Cache when the string you would use for a key is readily available and the content is always the same for each key. You should also use Cache when the content either contains no links or the when the bulk of the user population is expected to accept session cookies.

 
loading table of contents...