There are definitely some points in that code that need to be refactored. For instance - why reassign an app-scoped variable to the request scope in onRequestStart? Why not just refer to the app-scoped var in your view/client code?
Honestly, the code that was posted is too complex and too deep in your architecture to know how you're really using it. I also get the impression (based on the code posted) that you're using CFCs more as a function library than as a true OO system . . . which isn't necessarily bad, but it's hard to tell based solely on the code posted. I think that we need to get a CFC.Breeze conversation going to really understand what your intention is. It would make it *much* easier to diagnose, IMO. Sean used to host open Breeze sessions for this type of thing - if he still does this, it may be fun to discuss it there... I also have a 10 user Breeze account that we could discuss it over. Roland -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Hugo Ahlenius Sent: Thursday, March 30, 2006 2:32 AM To: [email protected] Subject: RE: [CFCDev] Application scope locking? Sorry, but your e-mail and code is a little bit too much for me to go through right now... (don't have the energy) Basically you shouldn't need any locking for simple vars and objects are probably passed by reference intentionally. For queries, structs and arrays, if you are modifying them throught the requests, you should probably duplicate or cflock them. It also depends on the level of encapsulation you need. -- Hugo Ahlenius ------------------------------------------------------------- Hugo Ahlenius E-Mail: [EMAIL PROTECTED] Project Officer Phone: +46 8 412 1427 UNEP GRID-Arendal Fax: +46 8 723 0348 Stockholm Office Mobile: +46 733 467111 WWW: http://www.grida.no Skype: callto:fraxxinus ------------------------------------------------------------- | -----Original Message----- | From: [EMAIL PROTECTED] | [mailto:[EMAIL PROTECTED] On Behalf Of Jason Daiger | Sent: Thursday, March 30, 2006 00:50 | To: [email protected] | Subject: [CFCDev] Application scope locking? | | Since I didn't get a single response on the first posting I thought | I'd try again. Below is a snippet of files used w/in an application. | I'm trying to figure out where the appropriate place (or whose job is | it) for locking application scope variables w/in these files. This is | post following up on the 'Application Scoped CFC' and the | 'application-scoped singletons and thread safety' threads from last | week. Like I said in my original post I'm not feeling like I got an | answer that clarifies things for me. | | Here's my issue, even if you var scope variables w/in functions w/a | CFC, use the 'variables' scope to store member data for that CFC, use | a factory to access the CFC and then place that factory w/in | application scope, where do I put the locks? Here's pieces of code | for 5 files (AppFactory.cfc, UserManager.cfc, Application.cfc, | dsp_User.cfm & | dsp_Users.cfm) to illustrate. (I've commented and omitted sections to | keep it as brief as possible.) | | General flow: Application.cfc fires 1st on a call, then either the | dsp_User.cfm or dsp_Users.cfm will fire and make calls to the | UserManager.cfc via the AppFactory.cfc. Reading and writing to | Application scope can occur during either call so where do I put the | locks? | | I'm hoping someone out there can help shed the light on this locking | issue for me. Here's the code along w/ my locking questions at the | bottom of the post. | | Thanks in advance, | Jason | | <!--- ================= AppFactory.cfc ================= ---> | <cfcomponent name="appFactory"> | <cffunction name="init"> | <cfset variables.me = structNew()> | <cfset variables.me.UserMgr = ""> | <cfset variables.me.dbMgr = ""> | </cffunction> | | <cffunction name="initDBManager"> | <cfargument name="dsn"> | <cfset variables.me.dbMgr = | createObject("component","DBManager").init(arguments.dsn)> | </cffunction> | | <cffunction name="getUser" returntype="User"> | <cfargument name="UserID"> | <cfif isObject(variables.me.UserMgr) eq false> | <!--- Note: omitting code to ensure me.dbMgr really has been | initialized for this example ---> | <cfset variables.me.UserMgr = | createObject("component","UserManager").init(variables.me.dbMgr)> | </cfif> | <cfreturn | variables.me.UserMgr.getUser(arguments.UserID)> | </cffunction> | | <cffunction name="getUsers" returntype="query"> | <cfif isObject(variables.me.UserMgr) eq false> | <!--- Note: omitting code to ensure me.dbMgr really has been | initialized for this example ---> | <cfset variables.me.UserMgr = | createObject("component","UserManager").init(variables.me.dbMgr)> | </cfif> | <cfreturn variables.me.UserMgr.getUsers()> </cffunction> | </cfcomponent> | <!--- ================= AppFactory.cfc END ================= ---> | | <!--- ================= UserManager.cfc ================= | ---> <cfcomponent name="UserManager"> | <cffunction name="init"> | <cfargument name="dbMgr"> | <cfset variables.me = structNew()> | <cfset variables.me.dbMgr = arguments.dbMgr> | <cfset variables.me.users = ""> | </cffunction> | | <cffunction name="getUser"> | <cfargument name="userID"> | <cfset var retVal = createObject("component","User").init()> | <cfset var local = structNew()> | <cfquery name="local.getUser" | dsn="#variables.me.dbMgr.getDSN()#"> | SELECT * FROM users WHERE user_id = #arguments.userID# | </cfquery> | <cfset retVal.setUserID(local.getUser.userID)> | <!-- Remainder of sets & code to ensure we actually have | something to set are omitted --> | <cfreturn retVal> | </cffunction> | | <cffunction name="getUsers"> | <cfargument name="userID"> | <cfset var retVal = createObject("component","User").init()> | <cfset var local = structNew()> | <cfquery name="local.getUser" | dsn="#variables.me.dbMgr.getDSN()#"> | SELECT * FROM users WHERE user_id = #arguments.userID# | </cfquery> | <cfset retVal.setUserID(local.getUser.userID)> | <!-- Remainder of sets & code to ensure we actually have | something to set are omitted --> | <cfreturn retVal> | </cffunction> | | <cffunction name="getUsers"> | <cfset var local = structNew()> | <cfif isQuery(variables.me.users) eq false> | <cfquery name="local.getUsers" | dsn="#variables.me.dbMgr.getDSN()#"> | SELECT * FROM users | </cfquery> | <cfset variables.me.users = local.getUsers> | </cfif> | <cfreturn variables.me.users> | </cffunction> </cfcomponent> | <!--- ================= UserManager.cfc END ================= ---> | | <!--- ================= Application.cfc - only applicable methods | shown ================= ---> | <cffunction name="onRequestStart" returnType="boolean" | output="false"> | 1 <cfargument name="thePage" type="string" required="true"> | 2 <cfif (structKeyExists(url,"init") eq true)> | 3 <cfif url.init eq "reload"> | 4 <cfset reloadAppScope()> | 5 </cfif> | 6 </cfif> | 7 <cfset variables.appFactory = application.appFactory> | 8 <cfreturn true> | </cffunction> | | <cffunction name="reloadAppScope" returntype="void" output="false" | access="private" hint="I reload the application scope variabes."> | <cfset var local = structNew()> | <!--- Determine Server Mode ---> | <cfif structKeyExists(application,"globalSettings") eq true> | <cfset structDelete(application,"globalSettings")> | </cfif> | <cfset application.appFactory = | createObject("component","com.myapp.AppFactory").init()> | <!--- Default Settings ---> <cfset | application.appFactory.initDBManager("myDSN")> </cffunction> | <!--- ================= Application.cfc END ================= ---> | | <!--- ================= dsp_User.cfm ================= ---> | 1- <cfset variables.aUser = | variables.appFactory.getUser(url.userID)> | 2- 3- <div>First name: #variables.aUser.getFirstName()#</div> | 4- <div>Last name: #variables.aUser.getLastName()#</div> | 5- <!--- Remainder of display form omitted ---> | <!--- ================= dsp_User.cfm END ================= ---> | | <!--- ================= dsp_Users.cfm ================= ---> | 1- <cfset variables.users = variables.appFactory.getUsers()> | 2- <!--- code outside loop omitted as it's just display stuff ---> | 3- <cfloop query="variables.users"> | 4- <tr> | 5- <td>#firstName#</td> | 6- <td>#lastName#</td> | 7- </tr> 8- </cfloop> | <!--- ================= dsp_Users.cfm END ================= ---> | | Now for the lock location question(s). Do I put an application level | lock on... | 1. Line 1 of dsp_Users.cfm since it might be writing to or reading | from an application scope variable? My answer is no since at that | 'level' it shouldn't know or care.. | 2. Line 1 of dsp_User.cfm since it might be reading from an | application scope variable? Again, I'd say no here. (FYI it's reading | the dsn variables stored in the DBManager which is in application | scope) 3. Any appropriate location w/in the UserManager.cfc? Again, | I'd say no here since that object should know or care about the | application scope. | 4. In every method w/in the AppFactory.cfc that reads or could write | to application scope? My gut tells me know b/c how does the appFactory | know what goes on in the UserManager? | It shouldn't so should it therefore lock everything? No way in my | opinion as that creates a bottleneck. | 5. Just don't bother? Can't be the right answer based on what I've | read so where do I put the locks? | | So my last option is to use duplicate on line 7 w/in the | onRequestStart method in my Application.cfc. <cfset | variables.appFactory = duplicate(application.appFactory)> | This makes some sense since the Application.cfc handles application | level locking w/in it but the amount of copying that one statement | might cause just does not seem right. So now what? I have no idea | and am looking forward to the suggestions that follow. | | Thanks again for reading this far.. | | -- | Jason Daiger | URL: www.jdaiger.com | EML: [EMAIL PROTECTED] | | | | | ---------------------------------------------------------- | You are subscribed to cfcdev. To unsubscribe, send an email to | [email protected] with the words 'unsubscribe cfcdev' as the subject | of the email. | | CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting | (www.cfxhosting.com). | | An archive of the CFCDev list is available at | www.mail-archive.com/[email protected] | | | | ########################################### This message has been scanned by F-Secure Anti-Virus for Microsoft Exchange. For more information, connect to http://www.f-secure.com/ ---------------------------------------------------------- You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email. CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com). An archive of the CFCDev list is available at www.mail-archive.com/[email protected] ---------------------------------------------------------- You are subscribed to cfcdev. To unsubscribe, send an email to [email protected] with the words 'unsubscribe cfcdev' as the subject of the email. CFCDev is run by CFCZone (www.cfczone.org) and supported by CFXHosting (www.cfxhosting.com). An archive of the CFCDev list is available at www.mail-archive.com/[email protected]
