JBossCacheCacheLoaders

NOTE: This article refers to an old version of JBoss Cache.  As of JBoss Cache 3.x "Naga" this information no longer applies.  Please refer to the JBoss Cache Official Documentation for information on configuring and setting up cache loaders.


1.  Intro: Configuring cache loaders in JBossCache 1.3.0

 

This page details configuring cache loaders in JBossCache 1.3.0 "Wasabi"

 

2.  Migrating from pre-1.3.0 cache loader configuration attributes

If you're used to using a pre-1.3.0 configuration file, you would be familiar with an XML block like such when setting up your cache loader:

        <!-- Old 1.2.x cache loader config block -->

        <attribute name="CacheLoaderClass">org.jboss.cache.loader.FileCacheLoader</attribute>
        <attribute name="CacheLoaderConfig">
          location=/opt/cacheloader
        </attribute>
        <attribute name="CacheLoaderShared">false</attribute>
        <attribute name="CacheLoaderPreload">/</attribute>
        <attribute name="CacheLoaderFetchTransientState">false</attribute>
        <attribute name="CacheLoaderFetchPersistentState">true</attribute>
        <attribute name="CacheLoaderPassivation">false</attribute>

 

While this format will still work with JBossCache 1.3.0 "Wasabi", it is deprecated.  We recommend migrating to the newer, more readable XML block structure detailed below and in the JBossCache 1.3.0 documentation.

 

2.1.  Why did we change this?

 

We were busy adding new features into the cache loaders and needed a better way to configure this.  One of the main changes is a redesign in the way cache loaders are created and used.  See below for details on this redesign.

 

3.  The new cache loader configuration XML block

 

This is what the same configuration defined above would look like using the new XML based configuration.

 

        <!-- New 1.3.x cache loader config block -->

        <attribute name="CacheLoaderConfiguration">
            <config>
                <!-- if passivation is true, only the first cache loader is used; the rest are ignored -->
                <passivation>false</passivation>
                <preload>/</preload>
                <shared>false</shared>

                <!-- we can now have multiple cache loaders, which get chained -->
                <cacheloader>
                    <class>org.jboss.cache.loader.FileCacheLoader</class>
                    <!-- same as the old CacheLoaderConfig attribute -->
                    <properties>
                        location=/opt/cacheloader
                    </properties>
                    <!-- whether the cache loader writes are asynchronous -->
                    <async>false</async>
                    <!-- only one cache loader in the chain may set fetchPersistentState to true.
                        An exception is thrown if more than one cache loader sets this to true. -->
                    <fetchPersistentState>true</fetchPersistentState>
                    <!-- determines whether this cache loader ignores writes - defaults to false. -->
                    <ignoreModifications>false</ignoreModifications>
                </cacheloader>

            </config>
        </attribute>

 

With more than one cache loader configured, it would look like:

 

 

        <!-- New 1.3.x cache loader config block -->

        <attribute name="CacheLoaderConfiguration">
            <config>
                <!-- if passivation is true, only the first cache loader is used; the rest are ignored -->
                <passivation>false</passivation>
                <preload>/</preload>
                <shared>false</shared>

                <!-- we can now have multiple cache loaders, which get chained -->
                <cacheloader>
                    <class>org.jboss.cache.loader.FileCacheLoader</class>
                    <!-- same as the old CacheLoaderConfig attribute -->
                    <properties>
                        location=/opt/cacheloader
                    </properties>
                    <!-- whether the cache loader writes are asynchronous -->
                    <async>false</async>
                    <!-- only one cache loader in the chain may set fetchPersistentState to true.
                        An exception is thrown if more than one cache loader sets this to true. -->
                    <fetchPersistentState>true</fetchPersistentState>
                    <!-- determines whether this cache loader ignores writes - defaults to false. -->
                    <ignoreModifications>false</ignoreModifications>
                </cacheloader>

                <cacheloader>
                    <class>org.jboss.cache.loader.JDBCCacheLoader</class>
                    <properties>
                        cache.jdbc.driver=com.mysql.jdbc.Driver
                        cache.jdbc.url=jdbc:mysql://localhost:3306/jbossdb
                        cache.jdbc.user=root
                        cache.jdbc.password=
                    </properties>
                    <async>false</async>
                    <fetchPersistentState>true</fetchPersistentState>
                    <ignoreModifications>false</ignoreModifications>
                </cacheloader>

            </config>
        </attribute>

 

 

3.1.  New cache loader design

 

The way the cache loaders are now designed, if you define a single cache loader as in the XML configuration above, the TreeCache instantiates and uses the cache loader directly.  If you were to define 2 or more cache loaders, the TreeCache creates an instance of org.jboss.cache.loader.ChainingCacheLoader - a delegate that also implements the org.jboss.cache.loader.CacheLoader interface - which maintains references to all configured cache loaders and propagates calls down to each one.

 

Note

NoteNoteNoteNote

the order in which you configured a chain of cache loaders is the order in which calls are passed down so it makes sense to have the faster cache loaders further up the chain. 

 

 

Write calls (put(), remove()) are passed to all cache loaders in the chain which have ignoreModifications set to false (see below).  Read calls (get(), exists()) are passed down the chain and the result of first cache loader that returns a non-null result is used.

 

3.1.1. org.jboss.cache.loader.CacheLoader interface changes

 

One very important change has been made to the CacheLoader interface.  It is not a programmatic one but it has to do with the expected behaviour of the get(Fqn fqn) method, that returns a Map of attributes for a given node.

 

From the JBossCache 1.2.4 Javadocs:

 

  /**
    * Returns all keys and values from the persistent store, given a fully qualified name
    * @param name
    * @return Map<Object,Object> of keys and values for the given node. Returns null if the node
    * was not found, or if the node has no attributes
    * @throws Exception
    */
   Map get(Fqn name) throws Exception;  

 

This means that you would get a null when making this call, and you would not know if it was because the node did not exist or the node did exist but just didn't have any attributes.

 

In JBossCache 1.3.0 this has been changed to:

 

   /**
    * Returns all keys and values from the persistent store, given a fully qualified name
    * @param name
    * @return Map<Object,Object> of keys and values for the given node. Returns null if the node is  
    * not found.  If the node is found but has no attributes, this method returns an empty Map. 
    * @throws Exception
    */
   Map get(Fqn name) throws Exception;

 

How does this affect me?

How does this affect me?How does this affect me?How does this affect me?How does this affect me?

If you have implemented a custom cache loader of your own, you will need to make sure it complies with the expected functionality set out by the CacheLoader interface or you may risk indeterminate results.

 

Elements that affect the entire cache loader chain

 

preload

 

This is the same as the old CacheLoaderPreload attribute and specifies a region of nodes to be preloaded into memory when the cache starts.

 

passivation

 

This is the same as the old CacheLoaderPassivation attribute and specifies whether you wish to use passivation.  When using passivation, only the first configured cache loader is used and others are ignored.  This defaults to false.

 

shared

 

This is the same as the old CacheLoaderShared attribute and should be used to indicate that the cache loader configuration used shares the same data stores (files, JDBC databases) as other instances in a cluster.  This will help optimise multiple nodes writing the same data repeatedly to the cache loader during replication.  This defaults to false.

 

Elements that affect individual cache loaders

 

class

This is the same as the old CacheLoaderClass attribute and configures a fully qualified class name of the cache loader to use.

 

properties

This is the same as the old CacheLoaderConfig attribute and specifies a list of properties to pass to the cache loader implementation.

 

async

This is the same as the old CacheLoaderAsynchronous attribute and specifies whether to make calls to the cache loader asynchronous.  This defaults to false.

 

fetchPersistentState

This is the same as the old CacheLoaderFetchPersistentState attribute and specifies whether caches retrieve state from remote caches' cache loaders when starting up.  This defaults to false.

 

ignoreModifications

 

Specifies whether write operations are performed on this cache loader.  This defaults to false.