OSCache - FAQ

Got a question you'd like to ask? Ask us and we'll add it to the FAQ. Questions What can I use OSCache for exactly? Where is the data cached? Can OSCache cache Java objects rather than portions of JSP pages? I mean if I create a Product object, can I cache it and use it later so that I don't have to fetch data again? What other features does OSCache have? Can you give me some examples of how the OSCache tags are used? Can OSCache tags be nested? What control do you have over the cache size? I can imagine the size of the in-memory cache getting very big. Is it possible to set a max cache size and then remove the least-recently-used entries from the cache? How does OSCache decide which object to remove? What caching algorithm does OSCache use? How does OSCache's clustering work? What happens if I need to expire data in the cache? Can you tell me more about grouping cache entries? How might this be used? I don't want to use the taglibs, I want to access OSCache directly from within my application. Where do I start? Where else can I go for help if I can't find an answer to my question here? #### What can I use OSCache for exactly? OSCache can be used on three different levels: JSP Caching - The first and simplest approach is to use the supplied taglibs to cache portions of JSP pages after the page has been rendered. This sounds simple but it's remarkably powerful and useful for almost every JSP application. Request Caching - OSCache comes with a filter that allows you to cache entire HTTP responses - including dynamically generated images! General-Purpose Cache - You can also use OSCache as a general-purpose caching solution by calling its API directly from your code. This allows arbitrary Java objects to be cached, and provides more control over the cache's behaviour. Note that any Java application can use OSCache in this manner; there is no requirement for a web server to be present when calling the API directly. All three approaches can be mixed and matched within the same application. #### Where is the data cached? Out of the box, OSCache is capable of caching data in memory (so it is very fast), and/or to disk (so your cache can be persistent across server restarts). Support is also provided for managing a cluster of caches across multiple servers. In addition to these capabilities, it is possible to plug in custom persistence code and custom event handlers, so you could easily extend OSCache to persist cached objects to say a database or an LDAP directory. #### Can OSCache cache Java objects rather than portions of JSP pages? I mean if I create a Product object, can I cache it and use it later so that I don't have to fetch data again? Yes, however to do this you will need to write code that talks to the OSCache API directly. The taglibs are currently only designed to cache rendered JSP content. This should hopefully not be too big a limitation since any creation or manipulation of java objects should generally be performed in beans or MVC action classes rather than JSP scriptlets anyway. #### What other features does OSCache have? There is a full list of features in the Feature List documentation. #### Can you give me some examples of how the OSCache tags are used? Example 1
    <cache:cache time="600">
            <%= myBean.getTitle() %>
        </cache:cache>
This will only access your EJB once every 10 minutes. Every other request it will just serve the cached JSP content that was produced the first time (this results in much faster page loading). Example 2
    <cache:cache key="foobar" scope="session">
            <%= myBean.getTitle() %>
        </cache:cache>
This time the cache is keyed (you could have a programmatic key here too, like <%= foobarString %>) and it's scoped by session. This is revolutionary as far as caching goes. You can now have cached content, that's different for every user! No more full page caches with no dynamic content! Example 3
    (a very powerful & useful way to use the taglibs):

        <cache:cache>
            <% try { %>
                <%= myBean.getTitle() %>>
            <% } catch (Exception e) { %>
                <% application.log("Exception occurred in myBean.getTitle(): " + e); %>
                <cache:usecached />
            <% } %>
        </cache:cache>
If a RemoteException occurs trying to get the EJB title (for example the database goes down) the cached content will be served so the user will not suspect a thing. No error page as per a normal JSP application. What does this mean? It means greater error tolerance in your JSP apps! One example of where this is useful - when our machine restarts, our app server loads faster than the database server. No problem - because the cache is persistent, it serves cached content while the database boots, then seamlessly kicks in to the database for a cache refresh when the database is ready. See the Tag Reference and the example web application for further taglib examples. #### Can OSCache tags be nested? You can't currently nest <cache> tags within one another - not that you'd probably want to. It is because of the cache object being placed in the page scope for use by programmers within the tag. We're not sure if anyone actually uses this so we might remove it to allow for tag nesting (presumably across includes or something). #### What control do you have over the cache size? I can imagine the size of the in-memory cache getting very big. Is it possible to set a max cache size and then remove the least-recently-used entries from the cache? You can limit the memory cache by the number of objects that are cached. When an object is added to the cache and the limit is exceeded, another object will be removed from the cache to make room. Currently the disk cache can either be set to unlimited, or tied to the same size as the memory cache (ie, objects will be removed from the disk cache at the same time as they are removed from the memory cache. Depending on the useage patterns of your cache, restarting your application could mean that the disk cache might continue to grow). We understand that this is not ideal and there is room for improvement here. Stay tuned! #### How does OSCache decide which object to remove? What caching algorithm does OSCache use? The caching algorithm is configurable. OSCache currently ships with 3 different algorithms - LRU (Least Recently Used), FIFO (First In First Out), and Unlimited. Should one of those not prove suitable, it is also possible to specify a custom algorithm class. #### How does OSCache's clustering work? The clustering is implemented as a listener that catches 'flush' events. These events are then broadcast across the network (using either the JavaGroups library or JMS) so that other nodes in the cluster can flush the relevant object(s) from their local cache. Note that for performance reasons, when objects are added to a cache they are not broadcast to other nodes. This means that each node in the cluster maintains their own relatively indedependent cache, yet still remains fresh. If this mechanism does not suit your requirements, you can always code up a different solution by writing a custom event handler. #### What happens if I need to expire data in the cache? Cache entries can be flushed explicitly in several ways: Individual entries can be flushed by specifying the cache key of the entry to flush eg <cache:flush key="myKey" scope="application"/> When adding an entry to the cache, it can optionally be placed into one or more groups. An entire group of entries can then be flushed by specifying the name of the group to flush. eg <cache:flush group="group1" scope="application"/> A pattern can be specified; all keys that contain the supplied pattern will be flushed. eg <cache:flush pattern="menu" scope="application"/> will flush all keys that contain the string "menu". (note that this approach is now deprecated. The cache grouping is more flexible and performs better than pattern flushing.) In addition, cached data can be expired at retrieval time by specifying a maximum age for the data, or by indicating what dates and/or times the data should expire. See the time, duration and cron attributes of the <cache> tag for more information. #### Can you tell me more about grouping cache entries? How might this be used? This is a powerful feature that makes it easy to manage your cache content. Suppose you are rendering a website and the pages that you are caching depend on various factors. Perhaps they use various shared templates, some database content, and maybe some of them depend on an external data feed. By creating a cache group for each of these factors, each cached page can be placed into the group(s) that the page is dependent on. Then when say an external datafeed is updated it is trivial to flush all pages that depend on that datafeed. Example 1:displayProduct.jsp
    ...
        <cache:cache key="myKey1" groups="product100,datafeed">
            <%= myProductBean.getProduct(100).getName() %>
            <%= myDatafeedBean.getDataFeed().getTotal() %>
        </cache:cache>
        ...
Example 2:updateDatafeed.jsp
    ...
        <%= myDatafeedBean.refreshDatafeed() %>

        <%-- Flush all cache entries that depend on the datafeed --%>
        <cache:flush group="datafeed" scope="application">
        ...
#### I don't want to use the taglibs, I want to access OSCache directly from within my application. Where do I start? We'd suggest the best place to start would be to look at the GeneralCacheAdministrator class. It provides a simple wrapper for a single cache instance and should give you all the basic functionality you need. If you want to work with multiple caches or manipulate your cache beyond what GeneralCacheAdministrator provides, consider either writing your own administrator class using GeneralCacheAdministrator as a starting point, or just create and use the Cache class directly. See the Javadocs for more information. #### Where else can I go for help if I can't find an answer to my question here? The best place to try is on the OSCache mailing list. It reaches a wide audience and is your best chance of getting a fast response. Remember to search the archives first to see if your question has already been answered. Got a question you'd like to ask? Ask us and we'll add it to the FAQ.