August 19, 2010
The Webex recording, Powerpoint slides and example code I used in last week's Boosting Performance and Scale for ColdFusion Applications with Ehcache webinar are now available. You can watch the recording here (note that registration is required):
Additionally, you can view the presentation slides:
Alternately, you can download the slides.
You can also download the sample code.
Please note that the examples created for blogCFC should only be considered a POC to demonstrate concepts and not production ready code.
August 9, 2010
I submitted a bug for this but the system seems to have swallowed it up without giving me the bug number (probably because I submitted as cf 9.0.1).
what I consider to be a serious bug an issue with ColdFusion's
ehache implementation and query objects that may bite you if you're not aware of how it works. If I take a query object and stick it in cache, then perform an operation on the original query
object such as adding a column or performing certain query of query
operations, ColdFusion is treating the query object that's in cache as
if it were a copy by reference to the original query object. That is,
if I make a change to the original query object, ColdFusion is also
applying the change to the version that's in cache. As far as I'm concerned, cache represents a boundary that ColdFusion
should not implicitly cross. With most caching systems I've worked with in the past (such as memcached), the cache always acted as a dumb key/value store. Unless I perform an explicit cachePut(), I wouldn't expect that CF would update values in the cache. Here's
two code snippets that reproduces the case. The first uses the
cfartgallery data source:
<cfquery name="getArtists" datasource="cfartgallery">
<!--- dump the original query --->
<!--- put the query in cache --->
<cfset cachePut("artistsQuery", getArtists,
<!--- add a column to the query --->
<!--- clear the query --->
<!--- get the query from cache again - note that the added column is
The second example shows how this can be done with a query of a query, based on a different bug Ray found previously (see http://www.coldfusionjedi.com/index.cfm/2009/8/28/Another-example-of-the-QofQ-Bug). In this sample, note that the date gets reformatted by the query of a query and both the original query and the cached version get updated:
<cfloop index="loop1" from="1" to="5">
<cfset newrow = queryaddrow(mydata, 1)>
<cfset temp = querysetcell(mydata, "mydate", #dateformat(now()-
<cfset temp = querysetcell(mydata, "rannum", 55.65, #loop1#)>
<cfset cachePut("myQuery", myData, '#createTimeSpan(0,0,5,0)#',
<cfquery dbtype="query" name="query4graph">
select mydate, rannum from mydata
The work around for this problem is to use the duplicate() function to make a clone of the query object before doing the cachePut(). Although this works, there are other potential consequences from having two copies of the query around, so be careful.
Update: It looks like this is actually expected behavior in Ehcache. Unfortunately, it's not documented in the ColdFusion documentation anywhere, but Ehcache actually has two configurable parameters (as of v. 2.10) called copyOnRead and copyOnWrite that determine whether values returned from the cache are by reference or copies of the original values. By default, items are returned by reference. Unfortunately we can't take advantage of these parameters right now as CF 9.0.1 implements Ehcache 2.0.
I can live with this, but it's not what I expected as I've always viewed Ehcache as a "dumb" key-value store and certainly didn't expect this behavior. Even if ColdFusion was running v 2.10 of Ehcache, it's still not something we could easily configure. Since ColdFusion currently doesn't have a cacheNew() function for creating new user-defined cache regions, the only way to turn this functionality off would be to hard-code your cache configuration in your ehcache.xml file for each user-defined region where you want to disable copyOnRead and copyOnWrite.
August 5, 2010
ColdFusion 9.0.1 added a new function called cacheGetSession() that returns the underlying cache object for Ehcache. What's really cool about this is that it allows you to get at just about all of the features available in Ehcache that aren't directly exposed to ColdFusion through built-in functions.
I was recently working on some example code for an upcoming caching presentation when I ran into a situation where I wanted to get a list of all caches that had been created on the server, including custom caches I had created myself. One simple line of code is all it took:
What you should note here is that even though I'm telling cacheGetSession() to get the cache object for the default object cache, getCacheManager() exposes a method called getCacheNames() which returns an array of cache names for the instance of cache manager. In the case of ColdFusion's Ehcache implementation, ColdFusion instantiates cacheManager as a singleton such that all caches are managed by the single cache manager. When you call getCacheNames(), it will return you a list of all caches currently implemented on the instance of ColdFusion.
While this may not be an issue for many people, if you are on a shared server it may be a concern. The only way to disable this is to disable the cacheGetSession() function using sandbox security.