eXo Platform 3.0

- Prev
- Next

## Chapter 55. eXo Cache

## Basic concepts

All applications on the top of eXo JCR that need a cache, can rely on an `org.exoplatform.services.cache.ExoCache` instance that is managed by the `org.exoplatform.services.cache.CacheService`. The main implementation of this service is `org.exoplatform.services.cache.impl.CacheServiceImpl` which depends on the `org.exoplatform.services.cache.ExoCacheConfig` in order to create new `ExoCache` instances. See the below example of `org.exoplatform.services.cache.CacheService` definition:

      <component>
        <key>org.exoplatform.services.cache.CacheService</key>
        <jmx-name>cache:type=CacheService</jmx-name>
        <type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
        <init-params>
          <object-param>
            <name>cache.config.default</name>
            <description>The default cache configuration</description>
            <object type="org.exoplatform.services.cache.ExoCacheConfig">
              <field name="name"><string>default</string></field>
              <field name="maxSize"><int>300</int></field>
              <field name="liveTime"><long>600</long></field>
              <field name="distributed"><boolean>false</boolean></field>
              <field name="implementation"><string>org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache</string></field>
            </object>
          </object-param>
        </init-params>
      </component>

### Note

The `ExoCacheConfig` which name is `default`, will be the default configuration of all the `ExoCache` instances that don't have dedicated configuration.

See the below example about how to define a new `ExoCacheConfig` thanks to a external-component-plugin:

      <external-component-plugins>
        <target-component>org.exoplatform.services.cache.CacheService</target-component>
        <component-plugin>
          <name>addExoCacheConfig</name>
          <set-method>addExoCacheConfig</set-method>
          <type>org.exoplatform.services.cache.ExoCacheConfigPlugin</type>
          <description>Configures the cache for query service</description>
          <init-params>
            <object-param>
              <name>cache.config.wcm.composer</name>
              <description>The default cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>wcm.composer</string></field>
                <field name="maxSize"><int>300</int></field>
                <field name="liveTime"><long>600</long></field>
                <field name="distributed"><boolean>false</boolean></field>
                <field name="implementation"><string>org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache</string></field>
              </object>
            </object-param>
          </init-params>
        </component-plugin>
      </external-component-plugins>

Table 55.1. Descriptions of the fields of `ExoCacheConfig`

name | The name of the cache. This field is mandatory since it will be used to retrieve the `ExoCacheConfig` corresponding to a given cache name.
label | The label of the cache. This field is optional. It is mainly used to indicate the purpose of the cache.
maxSize | The maximum numbers of elements in cache. This field is mandatory.
liveTime | The amount of time (in seconds) that an element is not written or read before it is evicted. This field is mandatory.
implementation | The full qualified name of the cache implementation to use. This field is optional. This field is only used for simple cache implementation. The default and main implementation is `org.exoplatform.services.cache.concurrent.ConcurrentFIFOExoCache`, this implementation only works with local caches with FIFO as eviction policy. For more complex implementation see the next sections.
distributed | Indicates if the cache is distributed. This field is optional. This field is used for backward compatibility.
replicated | Indicates if the cache is replicated. This field is optional. This field is deprecated.
logEnabled | Indicates if the log is enabled. This field is optional. This field is used for backward compatibility.

## eXo Cache extension

In the previous versions of eXo kernel, it was quite complex to implement your own ExoCache because it was not open enough. Since kernel 2.0.8, it is possible to easily integrate your favorite cache provider in eXo Products.

You just need to implement your own `ExoCacheFactory` and register it in an eXo container, as described below:

    package org.exoplatform.services.cache;
    ...
    public interface ExoCacheFactory {

      /**
       * Creates a new instance of {@link org.exoplatform.services.cache.ExoCache}
       * @param config the cache to create
       * @return the new instance of {@link org.exoplatform.services.cache.ExoCache}
       * @exception ExoCacheInitException if an exception happens while initializing the cache
       */
      public ExoCache createCache(ExoCacheConfig config) throws ExoCacheInitException;
    }

As you can see, there is only one method to implement which can be seen as a converter of an `ExoCacheConfig` to get an instance of `ExoCache`. Once, you created your own implementation, you can simply register your factory by adding a file conf/portal/configuration.xml with a content of the following type:

    <configuration>
      <component>
        <key>org.exoplatform.services.cache.ExoCacheFactory</key>
        <type>org.exoplatform.tutorial.MyExoCacheFactoryImpl</type>
        ...
      </component>
    </configuration>

## eXo Cache based on JBoss Cache

### Configuring the ExoCacheFactory

When you add, the eXo library in your classpath, the eXo service container will use the default configuration provided in the library itself but of course you can still redefined the configuration if you wish as you can do with any components.

The default configuration of the factory is:

    <configuration>
      <component>
        <key>org.exoplatform.services.cache.ExoCacheFactory</key>
        <type>org.exoplatform.services.cache.impl.jboss.ExoCacheFactoryImpl</type>
        <init-params>
          <value-param>
            <name>cache.config.template</name>
            <value>jar:/conf/portal/cache-configuration-template.xml</value>
          </value-param>
        </init-params>
      </component>
    </configuration>

As you can see, the factory requires one single parameter which is cache.config.template, this parameter allows you to define the location of the default configuration template of your jboss cache. In the default configuration, we ask the eXo container to get the file shipped into the jar at /conf/portal/cache-configuration-template.xml.

The default configuration template aims to be the skeleton from which we will create any type of jboss cache instance, thus it must be very generic.

### Note

The default configuration template provided with the jar aims to work with any application servers, but if you intend to use JBoss AS, you should redefine it in your custom configuration to fit better with your AS.

### Adding specific configuration for a cache

If for a given reason, you need to use a specific configuration for a cache, you can register one thanks to an "external plugin", see an example below:

    <configuration>
      ...
      <external-component-plugins>
        <target-component>org.exoplatform.services.cache.ExoCacheFactory</target-component>
        <component-plugin>
          <name>addConfig</name>
          <set-method>addConfig</set-method>
          <type>org.exoplatform.services.cache.impl.jboss.ExoCacheFactoryConfigPlugin</type>
          <description>add Custom Configurations</description>
          <init-params>
            <value-param>
              <name>myCustomCache</name>
              <value>jar:/conf/portal/custom-cache-configuration.xml</value>
            </value-param>
          </init-params>
        </component-plugin>
      </external-component-plugins>
      ...
    </configuration>

In the example above, I call the method addConfig(ExoCacheFactoryConfigPlugin plugin) on the current implementation of `ExoCacheFactory` which is actually the jboss cache implementation.

In the init-params block, you can define a set of value-param blocks and for each value-param, we expect the name of cache that needs a specific configuration as name and the location of your custom configuration as value.

In this example, we indicates to the factory that we would like that the cache myCustomCache use the configuration available at jar:/conf/portal/custom-cache-configuration.xml.

### Adding a cache creator

#### Understanding a cache creator

The factory for jboss cache, delegates the cache creation to `ExoCacheCreator` that is defines as below:

    package org.exoplatform.services.cache.impl.jboss;
    ...
    public interface ExoCacheCreator {

      /**
       * Creates an eXo cache according to the given configuration {@link org.exoplatform.services.cache.ExoCacheConfig}
       * @param config the configuration of the cache to apply
       * @param cache the cache to initialize
       * @exception ExoCacheInitException if an exception happens while initializing the cache
       */
      public ExoCache create(ExoCacheConfig config, Cache<Serializable, Object> cache) throws ExoCacheInitException;

      /**
       * Returns the type of {@link org.exoplatform.services.cache.ExoCacheConfig} expected by the creator
       * @return the expected type
       */
      public Class<? extends ExoCacheConfig> getExpectedConfigType();

      /**
       * Returns the name of the implementation expected by the creator. This is mainly used to be backward compatible
       * @return the expected by the creator
       */
      public String getExpectedImplementation();
    }

The `ExoCacheCreator` allows you to define any kind of jboss cache instance that you would like to have. It has been designed to give you the ability to have your own type of configuration and to always be backward compatible.

In an `ExoCacheCreator`, you need to implement 3 methods which are:

- create: this method is used to create a new `ExoCache` from the `ExoCacheConfig` and a jboss cache instance.

- getExpectedConfigType : this method is used to indicate the factory the subtype of `ExoCacheConfig` supported by the creator.

- getExpectedImplementation: this method is used to indicate the factory and the value of field implementation of `ExoCacheConfig` that is supported by the creator. This is used for backward compatibility, in other words, you can still configure your cache with a super class `ExoCacheConfig`.

#### Registering a cache creator

You can register any cache creator that you want thanks to an "external plugin", see an example below:

      <external-component-plugins>
        <target-component>org.exoplatform.services.cache.ExoCacheFactory</target-component>
        <component-plugin>
          <name>addCreator</name>
          <set-method>addCreator</set-method>
          <type>org.exoplatform.services.cache.impl.jboss.ExoCacheCreatorPlugin</type>
          <description>add Exo Cache Creator</description>
          <init-params>
            <object-param>
              <name>LRU</name>
              <description>The lru cache creator</description>
              <object type="org.exoplatform.services.cache.impl.jboss.lru.LRUExoCacheCreator">
                <field name="defaultTimeToLive"><long>1500</long></field>
                <field name="defaultMaxAge"><long>2000</long></field>
              </object>
            </object-param>
          </init-params>
        </component-plugin>
      </external-component-plugins>

In the example above, I call the method addCreator(ExoCacheCreatorPlugin plugin) on the current implementation of `ExoCacheFactory` which is actually the jboss cache implementation.

In the init-params block, you can define a set of object-param blocks and for each object-param, we expect any object definition of type `ExoCacheCreator`.

In this example, we register the action creator related to the eviction policy LRU.

#### The cache creators available

By default, no cache creator are defined, so you need to define them yourself by adding them in your configuration files.

##### LRU Cache Creator - Least Recently Used

    ..
    <object-param>
      <name>LRU</name>
      <description>The lru cache creator</description>
      <object type="org.exoplatform.services.cache.impl.jboss.lru.LRUExoCacheCreator">
        <field name="defaultTimeToLive"><long>${my-value}</long></field>
        <field name="defaultMaxAge"><long>${my-value}</long></field>
      </object>
    </object-param>
    ...

Table 55.2. Fields description

defaultTimeToLive | This is the default value of the field timeToLive described in the section dedicated to this cache type. This value is only used when we define a cache of this type with the old configuration.
defaultMaxAge | This is the default value of the field maxAge described in the section dedicated to this cache type. This value is only used when we define a cache of this type with the old configuration.

##### FIFO Cache Creator - First In, First Out

    ...
    <object-param>
     <name>FIFO</name>
     <description>The fifo cache creator</description>
     <object type="org.exoplatform.services.cache.impl.jboss.fifo.FIFOExoCacheCreator"></object>
    </object-param>
    ...

##### MRU Cache Creator - Most Recently Used

    ...
    <object-param>
      <name>MRU</name>
      <description>The mru cache creator</description>
      <object type="org.exoplatform.services.cache.impl.jboss.mru.MRUExoCacheCreator"></object>
    </object-param>
    ...

##### LFU Cache Creator - Least Frequently Used

    ...
    <object-param>
      <name>LFU</name>
      <description>The lfu cache creator</description>
      <object type="org.exoplatform.services.cache.impl.jboss.lfu.LFUExoCacheCreator">
        <field name="defaultMinNodes"><int>${my-value}</int></field>
      </object>
    </object-param>
    ...

Table 55.3. Fields description

defaultMinNodes | This is the default value of the field minNodes described in the section dedicated to this cache type. This value is only used when we define a cache of this type with the old configuration.

##### EA Cache Creator - Expiration Algorithm

    ...
    <object-param>
      <name>EA</name>
      <description>The ea cache creator</description>
      <object type="org.exoplatform.services.cache.impl.jboss.ea.EAExoCacheCreator">
        <field name="defaultExpirationTimeout"><long>2000</long></field>
      </object>
    </object-param>
    ...

Table 55.4. Fields description

defaultExpirationTimeout | This is the default value of the field minNodes described in the section dedicated to this cache type. This value is only used when we define a cache of this type with the old configuration.

### Defining a cache

#### How to define a cache?

You have 2 ways to define a cache which are:

- At `CacheService` initialization

- With an "external plugin"

##### At `CacheService` initialization

    ...
      <component>
        <key>org.exoplatform.services.cache.CacheService</key>
        <type>org.exoplatform.services.cache.impl.CacheServiceImpl</type>
        <init-params>
          ...
          <object-param>
            <name>fifocache</name>
            <description>The default cache configuration</description>
            <object type="org.exoplatform.services.cache.ExoCacheConfig">
              <field name="name"><string>fifocache</string></field>
              <field name="maxSize"><int>${my-value}</int></field>
              <field name="liveTime"><long>${my-value}</long></field>
              <field name="distributed"><boolean>false</boolean></field>
              <field name="implementation"><string>org.exoplatform.services.cache.FIFOExoCache</string></field>
            </object>
          </object-param>
          ...
        </init-params>
      </component>
    ...

In this example, we define a new cache called fifocache.

##### With an "external plugin"

    ...
      <external-component-plugins>
        <target-component>org.exoplatform.services.cache.CacheService</target-component>
        <component-plugin>
          <name>addExoCacheConfig</name>
          <set-method>addExoCacheConfig</set-method>
          <type>org.exoplatform.services.cache.ExoCacheConfigPlugin</type>
          <description>add ExoCache configuration component plugin </description>
          <init-params>
            ...
            <object-param>
              <name>fifoCache</name>
              <description>The fifo cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>fifocache</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="distributed"><boolean>false</boolean></field>
                <field name="implementation"><string>org.exoplatform.services.cache.FIFOExoCache</string></field>
              </object>
            </object-param>
    ...
          </init-params>
        </component-plugin>
      </external-component-plugins>
    ...

In this example, we define a new cache called fifocache which is in fact the same cache as in previous example but defined in a different manner.

#### How to define a distributed or a local cache?

Actually, if you use a custom configuration for your cache as described in a previous section, we will use the cache mode definde in your configuration file.

In case, you decide to use the default configuration template, we use the field distributed of your `ExoCacheConfig` to decide. In other words, if the value of this field is false (the default value), the cache will be a local cache, otherwise it will be the cache mode defined in your default configuration template that should be distributed.

#### LRU Cache - Least Recently Used

- New configuration

      ...
             <object-param>
              <name>lru</name>
              <description>The lru cache configuration</description>
              <object type="org.exoplatform.services.cache.impl.jboss.lru.LRUExoCacheConfig">
                <field name="name"><string>lru</string></field>
                <field name="maxNodes"><int>${my-value}</int></field>
                <field name="minTimeToLive"><long>${my-value}</long></field>
                <field name="maxAge"><long>${my-value}</long></field>
                <field name="timeToLive"><long>${my-value}</long></field>
              </object>
            </object-param>
      ...

  Table 55.5. Fields description

  maxNodes | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  minTimeToLive | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.
  maxAge | Lifespan of a node (in milliseconds) regardless of idle time before the node is swept away. 0 denotes immediate expiry, -1 denotes no limit.
  timeToLive | The amount of time that a node is not written to or read (in milliseconds) before the node is swept away. 0 denotes immediate expiry, -1 denotes no limit.

- Old configuration

      ...
            <object-param>
              <name>lru-with-old-config</name>
              <description>The lru cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>lru-with-old-config</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="implementation"><string>LRU</string></field>
              </object>
            </object-param>
      ...

  Table 55.6. Fields description

  maxSize | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  liveTime | The minimum amount of time (in seconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

  ### Note

  For the fields maxAge and timeToLive needed by JBoss cache, we will use the default values provided by the creator.

#### FIFO Cache - First In, First Out

- New configuration

      ...
             <object-param>
              <name>fifo</name>
              <description>The fifo cache configuration</description>
              <object type="org.exoplatform.services.cache.impl.jboss.fifo.FIFOExoCacheConfig">
                <field name="name"><string>fifo</string></field>
                <field name="maxNodes"><int>${my-value}</int></field>
                <field name="minTimeToLive"><long>${my-value}</long></field>
              </object>
            </object-param>
      ...

  Table 55.7. Fields description

  maxNodes | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  minTimeToLive | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

- Old configuration

      ...
             <object-param>
              <name>fifo-with-old-config</name>
              <description>The fifo cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>fifo-with-old-config</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="implementation"><string>FIFO</string></field>
              </object>
            </object-param>
      ...

  Table 55.8. Fields description

  maxSize | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  liveTime | The minimum amount of time (in seconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

#### MRU Cache - Most Recently Used

- New configuration

      ...
             <object-param>
              <name>mru</name>
              <description>The mru cache configuration</description>
              <object type="org.exoplatform.services.cache.impl.jboss.mru.MRUExoCacheConfig">
                <field name="name"><string>mru</string></field>
                <field name="maxNodes"><int>${my-value}</int></field>
                <field name="minTimeToLive"><long>${my-value}</long></field>
              </object>
            </object-param>
      ...

  Table 55.9. Fields description

  maxNodes | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  minTimeToLive | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

- Old configuration

      ...
            <object-param>
              <name>mru-with-old-config</name>
              <description>The mru cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>mru-with-old-config</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="implementation"><string>MRU</string></field>
              </object>
            </object-param>
      ...

  Table 55.10. Fields description

  maxSize | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  liveTime | The minimum amount of time (in seconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

#### LFU Cache - Least Frequently Used

- New configuration

      ...
             <object-param>
              <name>lfu</name>
              <description>The lfu cache configuration</description>
              <object type="org.exoplatform.services.cache.impl.jboss.lfu.LFUExoCacheConfig">
                <field name="name"><string>lfu</string></field>
                <field name="maxNodes"><int>${my-value}</int></field>
                <field name="minNodes"><int>${my-value}</int></field>
                <field name="minTimeToLive"><long>${my-value}</long></field>
              </object>
            </object-param>
      ...

  Table 55.11. Fields description

  maxNodes | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  minNodes | This is the minimum number of nodes allowed in this region. This value determines what the eviction queue should prune down to per pass. e.g. If minNodes is 10 and the cache grows to 100 nodes, the cache is pruned down to the 10 most frequently used nodes when the eviction timer makes a pass through the eviction algorithm.
  minTimeToLive | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

- Old configuration

      ...
            <object-param>
              <name>lfu-with-old-config</name>
              <description>The lfu cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>lfu-with-old-config</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="implementation"><string>LFU</string></field>
              </object>
            </object-param>
      ...

  Table 55.12. Fields description

  maxSize | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  liveTime | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

  ### Note

  For the fields minNodes and timeToLive needed by JBoss cache, we will use the default values provided by the creator.

#### EA Cache - Expiration Algorithm

- New configuration

      ...
             <object-param>
              <name>ea</name>
              <description>The ea cache configuration</description>
              <object type="org.exoplatform.services.cache.impl.jboss.ea.EAExoCacheConfig">
                <field name="name"><string>ea</string></field>
                <field name="maxNodes"><int>${my-value}</int></field>
                <field name="minTimeToLive"><long>${my-value}</long></field>
                <field name="expirationTimeout"><long>${my-value}</long></field>
              </object>
            </object-param>
      ...

  Table 55.13. Fields description

  maxNodes | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  minTimeToLive | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.
  expirationTimeout | This is the timeout after which the cache entry must be evicted.

- Old configuration

      ...
            <object-param>
              <name>ea-with-old-config</name>
              <description>The ea cache configuration</description>
              <object type="org.exoplatform.services.cache.ExoCacheConfig">
                <field name="name"><string>lfu-with-old-config</string></field>
                <field name="maxSize"><int>${my-value}</int></field>
                <field name="liveTime"><long>${my-value}</long></field>
                <field name="implementation"><string>EA</string></field>
              </object>
            </object-param>
      ...

  Table 55.14. Fields description

  maxSize | This is the maximum number of nodes allowed in this region. 0 denotes immediate expiry, -1 denotes no limit.
  liveTime | The minimum amount of time (in milliseconds) that a node must be allowed to live after being accessed before it is allowed to be considered for eviction. 0 denotes that this feature is disabled, which is the default value.

  ### Note

  For the fields expirationTimeout needed by JBoss cache, we will use the default values provided by the creator.

- Prev
- Up
- Home
- Next