I Want Your BrAAiIINS!!!

Because I couldn't decide if this blog entry should parody Uncle Sam or Night of the Living Dead. ;)

Yesterday I published Release Candidate 2 and rolled the version forward to 1.1 instead of 1.0 because there's actually been a significant amount of change to the system in the last 2 weeks, so I felt like RC2 should have a new minor version number as well.

The latest zip is available on the official site.

There are three major changes from RC1.

1) BRAINS!!

Recommendations for eviction policies are now handled by a separate intelligence.cfc which you can customize by copying to the /settings directory. This component ultimately doesn't make the recommendations itself, instead deferring to a collection of smaller components that I'm calling "brains". Each brain has one function to accept statistics for a caching agent and optionally return a single recommendation about how to configure the eviction policy for the agent.

In the Management Application there's now a link in the Options page to Optimize that displays a list of your agents with all the suggestions made by these brains for you to select the ones you want to apply (instead of simply applying them all as the RC1 release did). The auto-configuration routine is the same except that it stops at the first recommendation made for each agent, because it can only apply one.

I want your brains! This is an open challenge to all ColdFusion developers. There's some information in the documentation PDF about how to write a new brain object and I want to see what you can do with it! If your custom brain is any good, I'll include it in the next release. I may even offer some kind of prize for the best! :)

2) Email

You can now receive email alerts about predicted possible memory failures by copying the email.cfc into the /settings directory.

3) Logging

As with the email features, this is not enabled by default, however, there is now a complete logging tool. It includes the ability to log the service history (the general graphs you see on the Home tab of the Management Application), as well as changes to the agents (manual, automatic or both), and includes log rotation by size and/or by date.

Release Candidate 1

Hi all!

I just published the first release candidate for CacheBox. The 1.0 version includes a couple new features in the Management Application allowing you to get recommended optimizations either on the agent detail page where they can be optionally applied or by applying all recommendations for the server via the "Optimize Now" link on the Options tab.

Updating to the latest version will probably require a restart of your ColdFusion service.

Additional details in the release notes

CallBacks / Reap Listener

I've just uploaded a new build of the CacheBox core framework including a new version of the cacheboxagent.cfc and modifications to the service. These changes add support for a callback to your application when content is deleted or reaped from the cache, which Mark Mandel needed to integrate it with Transfer. This adds a new "ReapListener" init argument to the cacheboxagent.cfc following the "evict" argument, which accepts a CFC object. This object must have a single "ReapCache" method like this:

<cfcomponent displayname="ReapListener" output="false">
   
   <cffunction name="init" access="public" output="false">
      <cfreturn this />
   </cffunction>
   
   <cffunction name="ReapCache" access="public" output="false">
      <cfargument name="cachename" type="string" required="true" />
      <cfargument name="content" type="any" required="true" />
      <!--- execute clean-up code here --->
   </cffunction>
   
</cfcomponent>

Transfer Integration (coming soon)

So I got a message from Mark Mandel today asking me about ... wait for it ... callbacks. ;) Specifically he says he needs a callback when cache is reaped in order to write a CacheBox driven cache provider for the next release of Transfer. So I guess that's the use-case that I'd asked about on the blog here before. ;) Nobody responded to the previous blog, so I never got around to writing the code for the callback. I won't be able to work on it today - I'm in the midst of a big database migration project for a client. But hopefully I'll be able to start working on it on Thursday. :)

CF on Wheels Plugin

Mike Henke has taken the original CF on Wheels sample code that I created and turned it into a plugin for Wheels. Thanks, Mike! You can read more about it on the CF on Wheels discussion group here.

Quick Start

I'm posting this to satisfy curiosity for those of you who might like to see a clear code sample for CacheBox before you download the distribution. This is something that I could have done better when I gave the recent ColdFusionMeetup.com presentation, so it's also a bit of a follow-up for that. ;)

The only thing you actually need in order to implement CacheBox in your application is the CacheBoxAgent.cfc (it's actually all lower-case in the distribution, which is an important note for linux compatibility).

So you'll have to create an Agent object and you'll want to store it in your application for future use. If you're using a dependency injection (DI) framework like ColdSpring or Lightwire, of course you'll declare it there, otherwise something like this should work nicely. Remember to choose a descriptive name for your agent!

<cfset application.cachebox = CreateObject("component","cacheboxagent").init(
   AgentName = "my_cache"
   [, Context = "application"]
   [, Evict = "auto"]
   ) />

The context and eviction policy arguments are optional. Supported contexts include application, server and cluster (and they probably do precisely what you're thinking they do right now). There are a variety of available eviction policies including Age, Idle, Least Frequently Used (LFU), Least Recently Used (LRU), and First In First Out (FIFO), however, in most cases the default "auto" eviction policy should work nicely and is recommended. The auto policy allows the CacheBox service to decide what the most efficient eviction policy is for your cache, based on usage patterns and available resources.

If you're using this agent to store singleton objects that should never expire, you'll want to use "none" as your eviction policy.

Now that you have your agent, you can use it to store whatever cache you need. Cache is retrieved using the Fetch() method and set using the Store() method. Both methods return a structure with two keys: status and content. A status of 0 indicates everything is okay. Any non-zero status indicates some kind of cache failure.

<cfset myCache = application.CacheBox.fetch("myPage") />

<cfif myCache.status>
   <!--- non-zero status means the cache wasn't found --->

   <cfsavecontent variable="temp">
      ... generate the content here ...
   </cfsavecontent>

   <!--- store the content for later use --->
   <cfset myCache = application.CacheBox.store("myPage", temp) />
</cfif>

<cfoutput>#myCache.content#</cfoutput>

If you're storing singleton objects, you'll want to make sure that you return the content value from the store() operation, because that will guarantee that you're using the first (and only) object placed in cache. This only applies to objects - strings, structures and other kinds of content are simply overwritten when you store them.

Now if you need to selectively reset that item in cache, that's also easy to do:

<cfset Application.CacheBox.expire("myPage") />

That's all there is to it.

Frequently Asked Questions

Here are a couple of questions I received from Steve Bryant in email following yesterday's ColdFusionMeetup.com presentation.

Can it be used without installing the full monitor application?

Yes!

The only thing you need to integrate CacheBox into your application is the CacheBoxAgent.cfc. Just copy it out of the CacheBox distribution and put it directly into your own distribution and use it from there.

The CacheBoxAgent.cfc has its own simplified caching routines built-in that mirror the default storage type in the service, but with no eviction policy. If it's unable to access the service for any reason, then it will just fall-back to using its own internal caching engine. This is the feature that provides portability to the framework, and it's a point that I had intended to clarify in the presentation, but I think I didn't make it as clear as I wanted to, I think I unfortunately kind of glossed over that in the preso. ;)

I would like to be able to delete all caches for a given table in DataMgr. Could I do that in CacheBox pretty easily?

Yes, absolutely!

This is another point that I tried to mention, but I think I glossed over during the preso. Partly because I didn't show the code - someone asked a question about deleting content and I mentioned it briefly while answering the question.

So if you use the table name in your cache name, then you can use that as a handle to remove content from that table, using % as a wildcard just like you would in cfquery. So for example,

agent.expire("mytable.%")

This would expire all content for that agent where the cachename begins with "mytable.".

Presentation Recording

I somehow managed to announce this presentation for ColdFusionMeetup.com on my DataFaucet blog and onTap framework blog without remembering to post it here. D'oh!

We had a great time with yesterday's presentation. :)

We had an even dozen show up and a pleasant surprise at the end. There's a poll at the end of these meetup presentations so the people who attended can anonymously rate the presentation. It asks "was this information useful?" and the options range from 1-star (it was a waste of time) to 5-stars (yes, very much). In this case 50%, an even half of the guys who came gave me 5 stars. So I feel really good about the presentation. :) There is certainly still room for improvement in my presentation skills, but I think this is great progress.

I've also used some of the feedback from this presentation and updated the intro to the documentation for the CacheBox project to clarify the benefits of using it.

Here's the presentation recording for anyone who missed it: https://admin.na3.acrobat.com/_a204547676/p26212200/

Getting Size of Agent Cache - Fixed

I just committed some changes to the CacheBox SVN repository and pushed up a new 0.9.9 version. I realized suddenly that getting the occupancy of a specific agent isn't something I do very much of... but it was part of the CacheBoxAgent.cfc for people who might be interested in getting that metadata in their own apps.

It turns out because it's not something I do very often, that part of the CacheBox framework hadn't been well tested and the agent was attempting to call a method (getAgentSize) that didn't exist in the CacheBoxService.cfc. That lead me down the road of looking at a couple other methods and realizing that CacheBoxStorage.getHeadCount() wasn't being used anywhere and actually was redundant with CacheBoxStorage.getOccupancy() but the getOccupancy() method was missing an argument. D'oh!

Anyway I fixed all this stuff, rolled the version forward to 0.9.9 and unfortunately had to also roll the agent version forward to 1.4. I updated DataFaucet and the onTap framework with the new agent in their SVN repositories, but since those don't actually use the affected feature, I haven't published new archives for them yet.

Google Group

I already had a couple of google groups for the other two projects I maintain when Mike Henke asked me about a group for CacheBox, so I figured I should probably create one. :)

http://groups.google.com/group/cfcachebox

Railo Support

Hi all, I just wanted to bring everyone's attention to a new bug logged in our issue tracker by Bill Berzinskas. You can read the bug detail in our bug-tracker here: http://cachebox.riaforge.org/index.cfm?event=page.issue&issueid=E71EA06D-D85D-AED1-A198BFC1B17C10C4

I wanted to bring this up because I fully believe that the best software projects are those that have the active involvement of a committed (if small) team and I'd like for CacheBox to be one of those projects. I don't currently have a copy of Railo installed and I'm not sure when I'll have time to install one for testing. I would however love to include a patch from someone who works with Railo on a more regular basis. :) And I hope that you all are comfortable contributing to the bug tracker and contacting me with questions so that we can make this the best darn caching project we can make it!

Thanks!

More Entries

BlogCFC was created by Raymond Camden. This blog is running version 5.5.006. | Protected by Akismet | Blog with WordPress