A user sent in a request for me to look over some code he would like to use for his Application.cfc file. (As an aside, don't forget my online Application.cfc template you can use.) The template looked nice but had one main issue that I noticed. Since the user got the template from someone else, I won't post the whole thing as it isn't my code, but I will demonstrate the problem I saw.
First is the onSessionStart:
<cffunction name="onSessionStart" output="false"> <cfscript> session.started = now(); </cfscript>
<cflock scope="application" timeout="5" type="Exclusive"> <cfset application.sessions = application.sessions + 1> </cflock> </cffunction>
Notice that he is keeping count of the sessions, a topic I covered last week. Most importantly though - notice his lock. He is using a scope based lock to ensure his update of the application variable is single threaded. Now lets move on to the onSessionEnd method:
<cffunction name="onSessionEnd" output="false"> <cfargument name = "sessionScope" required=true/> <cfargument name = "applicationScope" required=true/> <cfset var sessionLength = TimeFormat(Now() - sessionScope.started, "H:mm:ss")>
<cflock name="AppLock" timeout="5" type="Exclusive"> <cfset arguments.applicationScope.sessions = arguments.applicationScope.sessions - 1> </cflock> </cffunction>
(Forgive the bad formatting - this came in via email.) Notice the problem? Try to figure it out before reading on.
He correctly uses a lock again to update the session count. But he can't use a scope lock since the application scope isn't available directly in onSessionEnd. That's why he has to use the application scope passed in via arguments.
So the problem then is that in one case he has a scope based lock and in another case he has a named based lock. He needs to use one or the other. Since he can't use a scope lock in onSessionEnd he should use the named based lock only.
p.s. A few other small things that I'll point out that are minor but bug me: I don't like using cfscript as he did here, just for one line of code. He also forgot the arguments prefix for sessionScope in onSessionEnd. I tend to be anal about using the arguments prefix in my methods.