November 17, 2009
In Part 5 of this series, we mentioned that Ehcache could be configured at runtime via ColdFusion code as well as by using an XML configuration file called ehcache.xml.
On a Java EE install of ColdFusion 9, you can find the ehcache.xml file located here:
There are two main sections of the file you need to be concerned with for basic configuration. The first section you should take a look at is the DiskStore configuration:
This tag tells Ehcache where it should write cache files if you have the cache configured to overflow to disk or to persist to disk. We'll get into the specifics of those options, but for now it's important to know that by default Ehcache will use your Java temp directory to store cache files if it is configured to do so. On Windows, the Java temp directory is located in c:/windows/temp. You can change the value here to any drive/directory on your system if you wish to use a location other than the Java temp directory.
The next section to take a look at comes at the end of the ehcache.xml file. Skip on down to the very end where you should see a block of XML that looks like this:
This block of XML tells ColdFusion how to configure all of the Object and Template caches that are automatically created for your application. When a cache is automatically created, the name for the cache is also automatically created using the convention appnameOBJECT for object caches and appnameTEMPLATE for template caches. Each cache has a number configurable parameters:
- maxElementsInMemory: Sets the max number of objects that will be created in memory. Once this limit is reached, the cache will either overflow to disk (if overflowToDisk is set to true), or the appropriate eviction policy will be executed against the cache to make enough room for the new item(s) being added.
- eternal: Sets whether elements are eternal. If eternal is set to true, timeouts are ignored and the element is never expired.
- timeToIdleSeconds: Sets the time to idle for an element before it expires.
- timeToLiveSeconds: Sets the time to live for an element before it expires.
- overflowToDisk: Sets whether elements can overflow to disk when the memory store has reached the maxElementsInMemory limit.
- diskSpoolBufferSizeMB: Specifies the spool buffer size for the DiskStore, if enabled. Writes are made to the spool buffer before they are asynchronously written to the DiskStore.
- maxElementsOnDisk: Sets the max number of objects that will be maintained in the DiskStore
- diskPersistent: Whether the disk store persists between restarts of the Virtual Machine.
- diskExpiryThreadIntervalSeconds: Specifies the interval (in seconds) between runs of the disk expiry thread.
- memoryEvictionPolicy: Policy to enforce upon reaching the maxElementsInMemory limit (LRU, LFU, FIFO).
If you make changes to any of these parameters, ColdFusion will apply them to any new caches that it automatically creates. If you have disk persistence or overflow to disk turned on, two files will be written to your file system per cache, an index file and a data file. For an object cache you would get appnameOBJECT.index and appnameOBJECT.data.
If you want to see what properties have been set for your application's cache, you can do so using the cacheGetProperties() function. The function takes a single optional parameter that specifies the type of cache to return the properties for. Options are Template or Object. If you don't specify the cache type to return properties for, ColdFusion returns them for both cache types. Here's an example that dumps the properties for both the default Object and Template caches:
This will result in output that looks like this:
As you can see from the screen shot, the structure keys correlate to parameters form the ehcache.xml file with two notable exceptions. Both diskSpoolBufferSizeMB and diskExpiryThreadIntervalSeconds are not reported on as properties that can be changed programmatically at runtime.
If you wish to change any of these properties programmatically, you can do so using the cacheSetProperties() function. This function takes a single argument – a structure containing all of the properties that should be configured. You can configure any of the following parameters:
- objectType: Specifies the cache type: Object, Template, or All
- diskStore: Supposed to specify the location of the DiskStore for disk based caching but this is currently not working as of ColdFusion 9.0.
- diskPersistent: Whether the disk store persists between restarts of the Virtual Machine. True|False
- eternal: Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. True|False
- maxElementsInMemory: Sets the max number of objects that will be created in memory. Integer
- maxElementsOnDisk: Sets the max number of objects that will be maintained in the DiskStore. Integer
- memoryEvictionPolicy: Policy to enforce upon reaching the maxElementsInMemory limit: LRU, LFU, FIFO
- overflowToDisk: Sets whether elements can overflow to disk when the memory store has reached the maxElementsInMemory limit: True|False
- timeToIdleSeconds: Sets the time to idle for an element before it expires: Integer number of seconds
- timeToLiveSeconds: Sets the time to live for an element before it expires: Integer number of seconds
Remember, this only applies to caches automatically created by ColdFusion. If a cache doesn't yet exist and you call cacheSetProperties(), ColdFusion will automatically create the cache for you based on whether you are setting properties for an Object cache, a Template cache, or both.
The following code shows how to build the structure of parameters necessary to configure a cache and set the cache properties using the cacheSetProperties() function:
<cfset myProps.diskstore = "c:/temp"> <!--- in the docs, but not currently implemented --->
<cfset myProps.diskpersistent = "true">
<cfset myProps.eternal = "false">
<cfset myProps.maxelementsinmemory = "5000">
<cfset myProps.maxelementsondisk = "100000">
<cfset myProps.memoryevictionpolicy = "LRU">
<cfset myProps.objecttype = "Object">
<cfset myProps.overflowtodisk = "true">
<cfset myProps.timetoidoleconds = "86400">
<cfset myProps.timetolivesecond = "86400">
<!--- update the cache properties --->
It's also possible to create more caches than just the default template and object caches that ColdFusion creates automatically for you. This can be achieved by defining them in your ehcache.xml file or at runtime using the cfcache tag. To configure a new cache region in your ehcache.xml file, you would do so like this (place this before or after the defaultCache block in your ehcache.xml file):
As you can see, the only difference between this code and the code for the default cache is that you give the cache region a name using the name parameter.
You should know that neither cacheGetProperties() nor cacheSetProperties() can be used to configure the properties for a custom cache in ColdFusion 9.0. Hopefully this is a feature that will be added in a future version of ColdFusion.
If you want to read from or write to a custom cache, you can only do so using the cfcache tag. Here's an example:
the custom object cache --->
<!--- if the item isn't there, it'll return null.
In that case, run the query and cache the
results and rerun the data from the db instead --->
<cfquery name="getArtists" datasource="cfartgallery">
<!--- dump the query from cache --->
<!-- dump the cache meta data --->
This code is almost identical to the code we wrote in Part 5 where we introduced the object cache (don't worry about the extra metadata we're pulling using cfcache. We'll cover that later). The only real difference is that here we specify a name for our cache in both cfcache tags by defining it in the key attribute. Key allows us to specify a custom name for our cache. If a cache by that name hasn't been configured in your ehcache.xnl file, ColdFusion will automatically create it using the parameters set in the default cache settings. Remember, you can only work with custom caches using the cfcache tag. None of the cache functions in ColdFusion 9.0 allow you to specify the cache name you want to apply the function to. Go ahead and run the code a few times to verify it's pulling from the custom cache.
There's a lot more advanced stuff that can be configured in the ehcache.xml file such as cache clustering. These topics deserve their own posts, which we'll get to soon. For now, thanks for sticking with the series and I hope you've learned a little more about the ins and outs of cache configuration in ColdFusion 9.