Caching: Frequently Asked Questions (Version 4.0 and Earlier)

Version 6

    Caching in Jive SBS usually refers to the back-end distributed memory cache technology, backed by Oracle Coherence.  In addition, there is a page-level cache web filter, and some render-layer filtering, but this document does not address these.

     

    This content applies to the caching system present in versions prior to 4.5.0. Documentation on caching in later versions will be available soon.

     

    There are two use cases for developers:

    • Using/interacting with existing caches
    • Creating new caches

    How can I learn more about Coherence?

    Coherence Cache Configuration Documentation

    When do I need to make my object Cacheable?

    You want to cache objects in order to keep them in memory to avoid making a database read. The Coherence cache is distributed memory cache, which means any server in your cluster will be able to read it from memory.  It's significantly faster to use the cache as opposed to a database call.  Ideally you want to make all of your persistent database objects cached.  If you don't read an object frequently it may not be necessary to make it cacheable.  However, experience shows that data has a tendency to become used more frequently over time and most things end up needing to be cached in the end.

    Are there other uses for caches than to avoid repeated DB reads?

    Yes, if you'd like to maintain server-side state across a cluster, a cache is the best place to do that.  We use that to track Document edit sessions, form tokens, login presence, etc.

    How do I tell if an object is reaching the cache?

    This can be a complex debugging process.  Ideally, you'd step through the code in a debugger.  You could also check for database calls; if they are being called repeatedly you can infer the object isn't being stored.  You can access the contents of the cache through the Coherence mbean (see Oracle site) or Coherence command line tools.

    How do I implement a cacheable object?

    You need to implement 2 interfaces: com.jivesoftare.community.cache.Cacheable, and optionally com.tangosol.io.ExternalizableLite.  Next, you don't want to hold onto object references of other objects you don't explicitly own.  E.g. you don't want to store a User object, you'd want to store the user id as a long.  In general try to hold Strings and primitives.

    When do I need to create a new cache?

    Generally, when you are creating a new database persisted object type you'd want to create a new cache devoted to it.  See the above answer about maintaining server state.

    Great, how do I create a new cache?

    1. Define your cache in coherence-cache-config.xml    See the Oracle site for documentation on this file.
    2. Define a cache bean in spring-cacheContext.xml

     

    NOTE: You don't write any new code to create a new cache, Coherence takes care of that for you if you define the cache in these config files.

     

    How do I access an item out of a cache?

    Cache implements the Map interface. The common idiom in backing a database call with a cache is to:

    public void loadObject(long objectId) {
        Object myObject = cache.get(objectId);
        if (myObject == null) {
            myObject = loadObjectFromDb(objectId);
            cache.put(objectId, myObject);
        }
        return myObject;
    }

     

    public void saveObject(Object myObject) {
        saveObjectToDb(myObject);
        cache.put(myObject.getId(), myObject);
    }

    How does Spring impact caching?

    Since the application uses Spring to instantiate the managers it's instantiating and injecting the Cache implementations to the managers.  See the spring-cacheContext.xml file to see the cache definitions.

    Can I configure a cache via plugin?

    Yes. Through the cache-config.xml file you deploy with your plugin.  See the plugin documentation.

    Are there any best practices for creating caches?

    Generally, you want to make defensive copies of objects you retrieve from the cache, i.e. cloning objects before returning them.   If you don't you run the risk of corruptiung data in the cache, e.g. if a form fails validation and partially edits the data.  Then the data in the cache can get out of synch with the database. Generally you want to write to the cache at the same time you're making the database call, most often in the same update method in the manager.

    What's the connection between caches and Managers?

    The pattern is to manage the interactions between the cache and persistence concerns in the manger layer.  The Manager implementations are where you should be putting cache access logic.

    Are there any differences between cache behaviors on a single node installation or a clustered implementation?

    Functionally, there should be no differences.  Behind the scenes, you're using different implementations; the single node implementation is optimized so that it doesn't make the network calls to maintain the distributed cache.