ColdFusion Muse

Ask-a-muse: Proper Use of Cachedafter

Mark Kruger March 18, 2008 5:43 PM Coldfusion & Databases Comments (3)

Muse Reader Asks:
I'm trying to use cachedAfter in a query. I have tried cachedAfter="#dateAdd("d", 1, now())# but it doesn't seem to ever cache after a day has passed. What am I doing wrong? cachedwithin seems to work fine.

This is one of those obscure tags that gets very little use in the community. I confess to never actually having found a use for it in production. Still, it bears some looking at because it is a clever notion that might come in handy under certain circumstances. Here's a primer:

The cachedafter attribute sets up the query to only cache if the query event is occuring after the date and time specified. This means your value has to be constant enough so that the threshold is crossed at some point. For example, if the value is set to 4:30 in the afternoon today, the query will continue to run "live" until 4:30, but the first time after 4:30 the query is run it will be cached - and it will be served from the cache from then on until a new "cahcedafter" value is given - or until something else clears the cache like the FIFO buffer or a restart. But in the example of the muse reader above this will never happen. The value of cachedafter will always be 24 hours into the future and therefore the server will never have any reason to cache it.

An Example

Here's a good example of when cachedafter might be effective. The "big three" stock exchanges open at 8:30 and close at 3:00 each day. Let us suppose that you are serving stock quotes from a data source using cfquery. If you wanted to always serve live data when the markets were trading you might set up some code like this:

<cfset hr = hour(now())/>
    
    <cfif hr IS 7>
        <cfset application.cachetm = CreateOdbcDateTime(dateformat(now(),'yyyy-mm-dd') & ' 15:00:00')/>
    </cfif>
    <cfquery name="getQuote" datasource="stocks" cachedafter="#application.cachetm#">
        SELECT    *    
        FROM    quotes
        WHERE    symbol = '#sym#'
    </cfquery>
This code would run "live" quotes till 3:00 and then cache the values until 7:00am the next day. At 7:00 am a new threshold is set and passed to the CFQUERY tag - at which point the server knows to not use the cache. At 3:00 it goes back to caching. Of course you would want to add a check for non-trading days and holidays but you get the idea. Notice that to use cachedafter you need some sort of manipulated value that changes periodically based on some condition. In this way, cachedafter is designed as a way to toggle caching on and off based on some stipulation that is met. I hope this helps. Keep those questions coming.

  • Share:

3 Comments

  • JC's Gravatar
    Posted By
    JC | 3/26/08 9:41 AM
    opposite problem, here... Mine was set to CacheAfter 6AM on the current date... but since it never got loaded before 6AM, it just kept showing the same stats every day.

    Solution -- Set up a scheduled task to load it every morning at 4am... fresh data with no 5 minute wait for query processing.

    Great, great tool for those big ugly daily reports that everyone needs to read and no one wants to wait for.
  • irv's Gravatar
    Posted By
    irv | 11/10/12 8:37 PM
    I'm working my way thru the best way to use cachedAfter and I'm thinking there's a small error in the text above. I think cachedAfter requires the cached query to be after a certain time as well as the current query. Of course the present query is always after the cached one. So... int he example above if a query is run at 2:59 PM and the next one is run at 3:15 it'll run "live" even though it's now after 3:00. From then on it'll use cache until 7:00 AM. Yes? No? Thanks!
  • John's Gravatar
    Posted By
    John | 2/28/13 1:49 PM
    I suppose this snippet is dependent on someone requesting the page during the 7th hour.