Now that ColdFusion 9 has been out for a few months, I've compiled a list of issues around caching that I'd like to see addressed in ColdFusion 9.0.1 or Updater 1. These are all issues that haven't already been discussed elsewhere or filed by others as bugs/enhancement requests.
To get the ball rolling, I'm listing each of the issues here along with the bug/enhancement number for the corresponding issue I filed in Adobe's ColdFusion Bug Database.
I have some additional things I'd like to see such as cache cluster configuration withing the CF Admin and an upgrade to Ehcache EX so that we can do true distributed caching within ColdFusion, but I'll address those items in a later post. For now, here's my list. I'm interested to hear how others are doing with the new caching in ColdFusion 9.
Ambiguous Error Message when Distributed Caching via RMI is Enabled and Server is not Connected to a Network (Bug 81840)
If you've configured your ehcache.xml file for clustering via RMI and you are not connected to a network, ColdFusion will throw an error if you try to perform any caching activities. This bit me at MAX when my network connection dropped before I started showing my examples. When I tried running any of my examples, I got the following error:The web site you are accessing has experienced an unexpected error.
Please contact the website administrator.
The following information is meant for the website developer for debugging purposes.
Error Occurred While Processing Request
error setting options
The error occurred in C:\_web\default\wwwroot\MAX2009\cache_get_put_function.cfm: line 1
1 : <cfset getArtists = cacheGet("artistQuery")>
2 :
3 :
________________________________________
Resources:
" Check the ColdFusion documentation to verify that you are using the correct syntax.
" Search the Knowledge Base to find a solution to your problem.
Browser Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Remote Address 127.0.0.1
Referrer http://localhost/max2009/
Date/Time 23-Oct-09 11:26 AM
Stack Trace
at cfcache_get_put_function2ecfm561514261.runPage(C:\_web\default\wwwroot\MAX2009\cache_get_put_function.cfm:1)
net.sf.ehcache.CacheException: error setting options
at net.sf.ehcache.distribution.MulticastRMICacheManagerPeerProvider.init(MulticastRMICacheManagerPeerProvider.java:93)
at net.sf.ehcache.CacheManager.init(CacheManager.java:241)
at net.sf.ehcache.CacheManager.<init>(CacheManager.java:221)
at net.sf.ehcache.CacheManager.create(CacheManager.java:415)
at net.sf.ehcache.CacheManager.getInstance(CacheManager.java:436)
at coldfusion.tagext.io.cache.ehcache.GenericEhcache.createCache(GenericEhcache.java:294)
at coldfusion.tagext.io.cache.ehcache.GenericEhcache._getCache(GenericEhcache.java:288)
at coldfusion.tagext.io.cache.ehcache.GenericEhcache.getCache(GenericEhcache.java:255)
at coldfusion.tagext.io.cache.ehcache.GenericEhcache.get(GenericEhcache.java:72)
at coldfusion.tagext.io.cache.CacheTagHelper.getFromCache(CacheTagHelper.java:226)
at coldfusion.runtime.CFPage.CacheGet(CFPage.java:8025)
at cfcache_get_put_function2ecfm561514261.runPage(C:\_web\default\wwwroot\MAX2009\cache_get_put_function.cfm:1)
at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:231)
at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:416)
at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:342)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:87)
at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:27)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
at coldfusion.filter.BrowserDebugFilter.invoke(BrowserDebugFilter.java:74)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:53)
at coldfusion.CfmServlet.service(CfmServlet.java:200)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
at jrun.servlet.FilterChain.service(FilterChain.java:101)
at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)
at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
This error only happens if you have RMI enabled in ehcache.xml and you aren't connected to a network. I don't expect this would ever be a problem in a production environment, but it could pop up on development machines – especially if people develop disconnected. At a minimum, I'd like to potentially see a more meaningful error message (even though you can narrow it down to RMI via the stack trace).
DiskStore Configuration is only Configurable in ehcache.xml (Bug 81841)
In ehcache.xml, there's a configurable property called<diskStore path="java.io.tmpdir"/>
You can change this to any path you want in ehcache.xml and it applies globally.
The ColdFusion documentation for the cacheSetProperties() tag currently shows that diskstore is a valid option:
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c18.html
My testing, however, has shown that is not working in the shipping build of ColdFusion 9. Try the following example (you'll need to create a directory off your root, c:/temp):
<cfset myProps = structNew()>
<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">
Before:
<cfdump var="#cacheGetProperties("Object")#">
<!--- update the cache properties --->
<cfset cacheSetProperties(myProps)>
After:
<cfdump var="#cacheGetProperties("Object")#">
<cfset cachePut("item1", "this is a test")>
If you run this code and check the c:/temp directory you should find it empty. Check your jave temp directory (c:/windows/temp on wintel) and you'll see that the files are still written there showing that the default value in ehcache.xml is being used and not the value being set in the cacheSetProperties() function.
The obvious action is to remove this attribute from the documentation until it can be implemented in a later version of ColdFusion. I would like to see it implemented, though, as I think it's useful to be able to set the diskstore location programmatically.
CacheGetMetadata() Returns both Cache Wide and Item Specific Metadata (ER 81842)
Currently, the cacheGetMetadata() function returns metadata that applies both to the individual cache item passed to the function as well as metadata for the entire cache region that the cached item came from. For example, if you have an item in the cache with an ID of "item1" and you can get the metadata for it like this:<cfdump var="#cacheGetMetadata("item1")#">
What this actually returns to you is a structure with two sets of information:
Cache_hitcount and cache_misscount apply to the overall cache. In other words, how many hits and misses the entire cache have received. The rest of the keys returned in the structure apply to the item passed in to the cacheGetMetadata() function.
I see a couple of potential issues with how this has been implemented. What I think we really need is two separate functions here. The existing cacheGetMetadata() should return just the metadata that is specific to the item passed to the function, not metadata on the entire cache. I would expect a separate function to retrieve metadata for the cache itself. To avoid confusion, I'd call the new function something like cacheGetStats(). In my mind it would return the cache_hitcount and cache_misscount that are currently returned by the cacheGetMetadata() function. It would also return a whole lot more that's available from ehcache but not exposed to ColdFusion – things like the total number of items currently in the cache, total size in bytes of all of the items in the cache, etc.
An Alternate Proposal for Additional ehcache Functionality (ER 81843)
What I think might be an even better and more future-proof solution for obtaining additional metadata (and more) from ehcache would be to provide similar functions to the ORMgetSessionFactory() and ORMgetSession() functions. If we had something like cacheGetSessionFactory() and/or cacheGetSession(), we could get access to all of the additional functionality in ehcache that's not currently exposed. Specifically this would give us an easy to get access to more cache statistics than we can access now, without having to write a bunch of new ColdFusion functions to handle things that might not be considered core or essential to caching.
Inability to Specify Cache Key in Functions (ER 81844)
The cfcache tag has the key attribute which allows you to specify a custom cache region other than the default template or object cache:<cfcache key="customCache" action="put" id="1" value="#now()#">
This creates a cache region at runtime called customCache. Getting, putting and flushing the cache are all supported from the cfcache tag. However, it's not currently possible to use any of the caching functions to operate on the custom cache region because there is no way to specify which cache region you want to use – the functions always apply to the default object or template cache.
I'd like to propose adding an optional attribute to all cache functions to allow a developer to pass in a custom cache region (key) for the function to operate against where applicable.
Naming Inconsistencies for Removing Cache Items (81845)
There are some naming inconsistencies between the cfcache tag and the new caching functions. To remove an item from the object cache using the cfcache tag, you use action="flush" like this:<cfcache action="flush" id="itemID">
Using a function instead, you use cacheRemove():
<cfset cacheRemove("itemID")>
Fragment Cache Gotcha (bug 81846)
I was just playing around some more with the template cache in ColdFusion 9 and noticed a behavior I hadn't expected that I think could potentially cause problems for people down the road.Consider the following example:
<cfcache>
This is a fragment
</cfcache>
<cfcache>
<cfoutput>
And so is this #now()#
</cfoutput>
</cfcache>
<cfdump var="#getalltemplatecacheids()#">
If you execute this, you'll get some output as well as a dump of all of the cached items in the template cache (getalltemplatecacheids is an undocumented function). At this point, there are two items in the cache:

Now say you weren't happy that the two lines of output on your page were all run together and you wanted to put a line break between each one. You might modify your code and add in a simple paragraph tag or line break like so:
<cfcache>
This is a fragment
</cfcache>
<p>
<cfcache>
<cfoutput>
And so is this #now()#
</cfoutput>
</cfcache>
<cfdump var="#getalltemplatecacheids()#">
Go ahead and run the code once you've inserted the
tag. What you'll now see is that you have three items in the cache:
What's happening is that ColdFusion is using the position of the code in your page as part of the ID for the cached item. When you inserted the
tag, the position of the fragment you cached also changed by moving down a few lines, and ColdFusion assumed you had added a new page fragment that you wanted to cache.
This may or may not be a big deal to people as CF will still pull the correct cached item every time. The gotcha is that if you have a lot of caching going on, and you're making a lot of changes in a development environment, it's possible to fill your cache up with a lot of junk pretty quickly.
I'm not making any statements on how this feature was implemented - I just want to make people aware of how the template cache works under the covers since it's not documented and if people are paying attention when they are developing they might see some things with the template cache that don't make sense if they don't know how it works.
cacheSetProperties() and cacheGetProperties() are Missing Configurable Parameters (ER 81847)
ehcache lets you configure a number of parameters for a cache region via the ehcache.xml file. ColdFusion exposes most of these configurable parameters at runtime using cacheSetProperties() and cacheGetProperties(). There are, however, 3 parameters which currently aren't exposed and can only be set within ehcache.xml:diskSpoolBufferSizeMB: This is the size to allocate the DiskStore for a spool buffer. Writes are made to this area and then asynchronously written to disk. The default size is 30MB. Each spool buffer is used only by its cache. If you get OutOfMemory errors consider lowering this value. To improve DiskStore performance consider increasing it. Trace level logging in the DiskStore will show if put back ups are occurring.
clearOnFlush: It determines whether the MemoryStore should be cleared when flush() is called on the cache. By default, the MemoryStore is cleared. Useful is you want to back up a cache to the file system without clearing the MemoryStore.
diskExpiryThreadIntervalSeconds: The number of seconds between runs of the disk expiry thread. The default value is 120 seconds.
I'm not sure why these were left out but it would be nice if they were also included in the configurable properties using ColdFusion functions.




























