So a few days ago I wrote a quick blog entry asking why more people weren't making use of Trusted Cache. While not a silver bullet, it can sometimes be a quick way to improve your site performance. A reader, johans, commented asking what the impact would be on files stored in the virtual file system (VFS). I assumed it would act the same - ie, any changes would not be picked up. Today I wrote a quick template to see if I was right:
<cfoutput>My number is #num#<p/></cfoutput> <!--- note, RAM mapping was made in cf admin --->
<cfinclude template="/RAM/foo.cfm">
<cfset num = randRange(1,9999)>
<cfset content = "<cfoutput>Your num is #num#</cfoutput>">
<cfset fileName = "ram://foo.cfm">
<cffile action="write" file="#fileName#" output="#content#">
When run, this code creates a random number and writes the CFML to display it to a file in the vfs. Yes, the code is dumb. There is no need to use cfoutput in this case. But I wanted to ensure I had some dynamic code in the VFS. After writing it, we output the number and include the template. Don't forget you can't cfinclude a file via a full physical path. I made a mapping in the CF Admin for my VFS called RAM and included it like that.
Before turning on trusted cache, I ran this template a few times and saw what I expected - the same number in both outputs. After turning on the trusted cache, the number in the VFS "froze" since ColdFusion wasn't picking up on the changed CFM. (Which is expected - this isn't a bug.) To be clear, ColdFusion is still writing the file out and changing it. That part works fine. It's just the compiled version of the CFM that is being cached and reused. Clearing the trusted cache immediately brought out the new number.
So what if you want to make use of the VFS like this and make use of the trusted cache? Well if we assume you aren't writing to a static file on every request, you can simply use the Admin API to clear it. If you do need something for every request you could consider unique file names. Just be sure to "clean up" or your VFS will fill up eventually.
Archived Comments
I turned it on, but for some reason, when I would check out a page, make a change, then check the page back in, it was not showing the updated page on the server. Even though, the page on the live server was correct, it was not showing up in the browser. The Trusted Cache still retained the old copy. Once I turned it off, the new page showed up just fine. This was not a good solution for us, especially since we use Contribute for many of the dept. offices to update their sections, and they were not seeing the published pages show up.
rgreen - I do not think you read my previous entry. This is expected with Trusted Cache turned on. The performance you get has the trade off of CF not picking up on changes to your code. Please go and read that previous entry (linked to above) as I talk about this and ways around it.
I didn't read everything close enough. When I looked in the CF Admin, and read the text, I missed the part that stated: "For sites where templates are not updated during the life of the server" and clicked it on anyway. It was my bad.
I do it all the time - don't feel bad. :)
Don't forget though that there are ways around it.
New question. Is there anyway to flag a template, or a whole directory as being excluded?
Two cases I see are:
1. On the server I have a file or files that I create to run a quick script against the database or other code, and usually I write it and test as I go. It's a pain to clear that file each time I fiddle with it. (In this case I guess I could write a custom tag to include to try to clear the calling file from the cache.. or something.)
2. Most of the code doesn't change, but there may be a site in progress, any way at all to say cache all but this folder?
Thank you for your awesome tips.
So it would be nice if there was a way to ensure the cfinclude CFML code remained executable in the compiled template and is not replaced by the included code. Maybe something like a "cfrun" tag.
I think Railo has a function to run CFML without having to resort to cfinclude.
Not quite sure I get what you mean. My example does let you execute CFML code. It _was_ executable, just cached.
Tim - no - when the feature is on, it caches everything.
I was really hoping, for those single templates to be able to do this:
<cfset createObject("component","cfide.adminapi.administrator").login(":-p")>
<cfinvoke component="cfide.adminapi.runtime" method="clearTrustedCache" templateList="#GetBaseTemplatePath()#">
I think it should work, cause CF would cache the code.. and then run it, and the running would uncache it..
Sure - that works. Or should work. Give it a shot. :)
No, it's not working,I tried wrapping it in a custom tag, which would be handy to stick o pages I don't want kept in the cache. I keep getting an error:
The error occurred in runtime.cfc: line 661
Called from E:\wwwroot\tmp\dontCache.cfm: line 3
Called from E:\wwwroot\tmp\___notes___.cfm: line 4
-1 : Unable to display error's location in a CFML template.
I feel like I'd need to do some kinda of after the fact delayed execution (onRequestEnd?), but maybe it's not quite worth it.
Oh dude - your code is a bit wrong. You want to change your first line to actually return an object.
<cfset ob = createOb....
Then in line to change component="..." to component="#ob#". Not sure that will work - but it may.
Don't automatically go in and flip this switch on without testing first.
One CMS that I know of saves bits and pieces of pages out as CFM files and includes them as needed.
Which works fine until a user posts an update and the CMS writes out a new file... which is then ignored by a system with Trusted Cache enabled.
We had similar issues, but realized if we implemented a fileRead into a variable and output the variable it worked as expected. This means you must run your logic when creating the file rather than when processing the file on the include. We were using .txt files but I imagine fileRead in a cfm would act the same.