Adobe Livedocs Error

Word Count: 184

Today I was trying to look something up on Adobe Live docs and I came across an interesting error. I am not posting this error in the wild to point fingers at people because believe me I am far from perfect. I think this is a perfect opportunity to look at a couple of things that might of prevented this error.

Before we get into a solution we need to look at the problem. So as I was browsing the live docs today I saw the following page displayed.


Without more information I can't be sure what's going on here but I can take a stab at it. The first issue is with locking application variables. The reason you want to lock variables is because in a multi threaded environment you can have the chance (albeit slim chance) of 2 threads attempting to do the same thing at one time. I used to see this code all the time (even in my own stuff).

I still see this code in onRequest methods of the application cfc which is a no no. The application component gives a great method for this, onApplicationStart. You might of already known that but what you might not of known is that this method is single threaded so you don't have to worry about locking your variables. It's important to remember though, if you call this method manually it is no longer single threaded (something to keep in mind).

The other problem is this page is dumping out an error to screen. This can be easily avoided but it's extra work and honestly I am guilty of it as well. I could explain error handling to you but there is no need to. Ray Camden has an excellent article on Adding error handling to your ColdFusion application that I highly recommend.

Again, I am not picking on Adobe because I am far from perfect but when errors like this come up its always a good reminder to us what we can do to avoid them.

Comments

#1 Posted By: Steve Withington Posted On: 5/6/09 2:53 PM
Please help clarify something for me ... so if I call for example <cfset onApplicationStart() /> from within my onRequestStart method, should I wrap that like so:

<cflock type="exclusive" scope="application" timeout="60">
<cfset onApplicationStart() />
</cflock>
#2 Posted By: Dan Vega Posted On: 5/6/09 2:59 PM |
Author Comment
If you are calling onApplication start like you would be there then yes you need to manually lock it. I am actually trying to think of a good example for this but just know that in that instance you are multi threaded and take the chance of 2 threads running the same method.

If anyone has a good example of a race condition that could take place here please help me out.
#3 Posted By: Steve Withington Posted On: 5/6/09 3:20 PM
Are you also recommending people lock "THIS" vars too? For example:

<cflock type="exclusive" scope="application" timeout="60">
<cfset this.customTagPaths = getDirectoryFromPath(getCurrentTemplatePath()) & "extensions/customtags/" />
</cflock>
#4 Posted By: Dan Vega Posted On: 5/6/09 3:23 PM |
Author Comment
That is an interesting question! I would hope the variables in the "this" scope here would be read only but I am not sure about that. Does anyone know the answer to this? If you grab the page context can you overwrite these variables?
#5 Posted By: Todd Rafferty Posted On: 5/6/09 4:35 PM
My understanding is you no longer need to use cflock for anything other than protecting against race condition or protection against multiple apps changing values at the same location.

No one from Adobe will come out and state this publicly, but all of the locking issues went away when they moved to the MX platform.

Dan is right about OnApplicationStart / OnSession start though, if you invoke that by <cfset onSessionStart()> it is not single threaded.

http://www.coldfusionguy.com/ColdFusion/blog/index...

http://www.bennadel.com/blog/1123-CFLock-And-Negat...
#6 Posted By: Todd Rafferty Posted On: 5/6/09 4:40 PM
Regarding "this.customTagPaths" - Keep in mind as soon as a custom tag is found (local or otherwise), the path to the custom tag is now memorized by the server. As Ben found out today:
http://www.bennadel.com/blog/1583-ColdFusion-8-Per...

getDirectoryFromPath(getCurrentTemplatePath()) is fine to use during development, but when you go to production, you'd want that to be a static path. Anything that has to hit the system os to determine what the "path" is going to add up. File/System operations are expensive.

Not sure what locking it would protect you from. The only way to modify it would be within the Application.cfc
#7 Posted By: Steve Withington Posted On: 5/6/09 5:14 PM
Thanks guys. I'll have to admit not using CFLock much on "Application" but more on "Session" vars. For example:

<cflock scope="session" timeout="5" type="exclusive">
<cfset session.started = now() />
</cflock>

As for the dynamic path ... it's just something I've always done so I can make my code more "plug-in & run" so I guess I'll have to take a closer look at that.
#8 Posted By: Todd Rafferty Posted On: 5/6/09 5:30 PM
@Steve: Plug 'n run is good. Just beware of the overhead. Keep in mind, everyone uses it. If it were a major issue, I'm sure people would have been clamoring for an explanation.
#9 Posted By: Todd Rafferty Posted On: 5/15/09 8:29 AM
@Steve: Been thinking about this issue a little more. It's better if you did this:
this.mypath = getDirectoryFromPath(getCurrentTemplatePath());
this.customTagPath = this.mypath & "extensions/customtags/";
etc.

In other words, execute "getDirectoryFromPath(getCurrentTemplatePath())" once and only one time. That's 1 hit on the system as opposed to 1+ hits (especially if you're using it for mappings as well).


Post Your Comment

Leave this field empty







Show Captcha

If you subscribe, any new posts to this thread will be sent to your email address.

Copyright © 2007 Dan Vega | BlogCFC was created by Raymond Camden. This blog is running version 5.8.001.