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]


Reply via email to