Rob Brooks-Bilson
Tech, Photography, Stuff
Tech, Photography, Stuff
November 16, 2009
In previous versions of ColdFusion (before ColdFusion 9 that is), there were three built-in mechanisms you could for caching – persistent variable scopes, query caching and the cfcache tag. As I mentioned in Part 2 of the series, each of these methods has inherent limitations and generally requires a good deal of additional programming to gain any semblance of control over the actual cache – if that is even possible. In many cases it really isn't practical or even possible to see how much information is stored in one of the aforementioned caching mechanisms. All of this changes with the introduction of Ehcache as the underlying cache provider in ColdFusion 9. Five parts into this series, and I just realized I've mentioned Ehcache several times but I never really took the time to talk about what exactly it is and how it's been implemented in ColdFusion 9.
The Ehcache project was started by a gentleman named Greg Luck. Ehcache can best be described as "... a widely used Java distributed cache for general purpose caching, Java EE, and lightweight containers." Caches are implemented as key-value stores, much like a ColdFusion structure. One important feature of an Ehcache cache is that it can be persisted to memory, disk, or both. Optionally, memory caches can be configured to survive JVM restarts (or in our case, ColdFusion server restarts). Caches can be configured via an XML configuration file named ehcache.xml or programmatically at runtime. Ehcache ships as a JAR file and runs in-process within an application server's JVM. In the case of ColdFusion 9, the JAR file and the XML file used to configure it (ehcache.xml) are both located in:
/JRun4/servers/server_name/cfusion-ear/cfusion-war/WEB-INF/cfusion/lib
ColdFusion 9 implements three types of caches using the Ehcache engine: Template Caches, Object caches and Hibernate Caches. Each of these cache types has their own use cases and we'll cover them in depth in future blog posts. For now, here's a quick summary of what each cache type is and generally what it's used for.
The template cache is designed for caching entire web pages as well as page fragments (sections of web pages). You shouldn't confuse this with the template cache mentioned in the ColdFusion Administrator. That template cache is concerned with compiled ColdFusion templates stored in memory. It's unfortunate that this dual use of the term "template cache" exists in ColdFusion so you need to be aware of which type of cache is being referred to when you see template cache mentioned. In terms of the Ehcache template cache implementation in ColdFusion 9, it's a fairly automatic process with ColdFusion handling the bulk of the work managing keys, cache gets/puts and expiry/eviction from the cache. Working with the template cache is done exclusively using the cfcache tag. Here's a very basic example:
In this code, the first section displays the current date/time. The second section uses the cfcache tag with action="serverCache". This action specifies that we want to use server side caching (Ehcache) and is now the default action in ColdFusion 9. To cache a fragment of code in a ColdFusion page we simply have to wrap it in a cfcache block. The next section of code is again entirely dynamic. The fourth and final section is wrapped in another set of cfcache tags. When you execute this code for the first time, the output will show the same date/time for all four sections of code, like this:
Running the code a few seconds later has different results:
In this case, the output contains both dynamic data (the first and third lines) as well as cached data (the second and fourth lines). Using the template cache it's easy to see how you can mix both dynamic data and multiple fragments of data that needs to be cached on the same page. There's really not a whole lot for you to do. You simply wrap the content you want to cache in a cfcache block and ColdFusion handles the rest. There are a few things you can control like cache timeouts, but we'll cover that in a full blog post dedicated to the template cache and all of it's features.
The object cache gives you much more granular control over what you cache than the template cache does. Using the object cache, you can pretty much cache anything you want – simple values, complex variables, objects, files, and just about anything else you want to throw at it. The advantage to using the object cache is that you have complete control over key names, get/put/remove operations, and cache expiry/eviction. This takes a little more work on your part but what you give up in convenience you easily gain back in flexibility and control. You can work with the object cache using both the cfcache tag as well as the new caching functions introduced in ColdFusion 9. Here's a very basic example of how you can cache the results of a query in an object cache using the cfcache tag:
In this code, the first thing we do is try to pull our query out of the cache using the cfcache tag with action="get". The key that identifies our cached query in the object cache is set using id="artistQuery". Of course the first time we run this the query won't be in the cache, so the result variable we specified (name="getArtists") will return Null. After we attempt to pull the query from the cache, we then use the isNull function to see if anything was returned from our get operation. If getArtists is Null, we know that the query data isn't in the cache so we need to run our query, retrieve the data and then place it in the cache using the cfcache tag with action="put". When we do our cache put, we set id="artistQuery", which is the name of our cache key. The value to store in the cache is our ColdFusion query (value="getArtists") and we can specify how long the data should be cached using the timespan argument. The first time you execute the page (with debugging turned on), you'll notice that there's debugging information for your executed SQL Queries – because the query data didn't exist in the cache yet and you told ColdFusion to go off and get it from the database and put it into the cache. If you execute the page again, you won't see any debug info for your SQL Queries because ColdFusion is pulling the data from the cache and not from the database. It's important to note that in the dump of the query data from this example, Cached will always be False, regardless of whether you are accessing cached data or not. This is because Cached refers to whether or not the result set is in the ColdFusion Query Cache, which it is not because we are using Coldfusion's Ehcache implementation here and not the built in query cache. There's a lot more you can do with the object cache which we'll cover in another blog post.
If you're using ColdFusion 9's new Hibernate ORM functionality you can configure the ORM such that it uses Hibernate as its second level cache. This is a more complicated topic that we have time to discuss now, so let's table it for another blog post.
When you create a ColdFusion application and your application uses an Application.cfc or Application.cfm file, ColdFusion automatically creates a template cache and an object cache for you. These caches are bound to your application name (defined in your cfapplication tag for an Application.cfm file or this.name if you are using Application.cfc). If you have an unnamed application, ColdFusion will create a cache that is shared and accessible among all unnamed applications. It's important to remember that caches are not tied to ColdFusion scopes. If your application times out, this does not affect the cache(s) you create with Ehcache.
That's about it for getting to know the basics of Ehcache in ColdFusion 9. In Part 6 we'll start looking at the ehcache.xml file and how it can be used to configure the behavior of the caches you create in ColdFusion 9.
11/17/09 9:49 AM
Good post, especially the stuff at the end. Thanks