I think we only need to use the duplicate() function when we set the
request variable, not when we set the application variable. i.e.
use it here:
<cfset request.app=duplicate(application.requestapp)>
no need to use the duplicate() function here:
<cfset application.requestapp=request.app>
is that right?
Steve
BOROVOY Noam wrote:
>
> Thought we bashed this one out a while back:
> The "pointers" or "references" might be stored in thread safe memory (like
> the request scope) but the memory they point to (or reference) is NOT thread
> safe.
>
> Here's my current approach to tackle this problem (based on the accumulated
> tips from the list):
> In App_globals
> 1. set simple globals into the request scope - no locking issues - tiny
> performance hit on setting all the values for each request probably equal or
> less than the hit of locking.
>
> 2. set structures / arrays into the application scope - first check if
> already defined and loaded - do a full check using IsDefined followed by
> isArray / IsStruct and a check for minimum size - just in case there was a
> DB error on the previous load.
> Then if not defined Write lock and load the data from the DB - i.e. define
> the data element, include the needed query and fill it up.
> If defined do nothing it's already there for you to use.
>
> 3. In Index.cfm wrap the whole file after the include of app_locals with a
> read lock. (if you reference any application vars in app_locals you will
> want to lock that as well after the include of app_globals.
>
> The read locks will not hit performance - they will only affect performance
> on the first hits after a reboot and once the application variables time out
> and need to be re-loaded - which should hardly happen on a busy site.
>
> So Steve - only two locks for the whole application - just placed in
> different locations ;-)
>
> For session vars things get messier as you want to write to them deep down
> in the application - but I found that a well designed app can usually avoid
> the need for session variables and if really needed use client vars or do
> the locking everywhere...
>
> HTH,
> Noam
>
> ----------
> From: Fred T. Sanders [SMTP:[EMAIL PROTECTED]]
> Sent: Monday, 28 August 2000 16:30
> To: [EMAIL PROTECTED]
> Subject: Re: No more need for cflock!!
>
> Yes it does only set a pointer, I've tested that before and found it
> to be
> the case.
> However (and I haven't tested this) the request scope by its very
> definition
> in CF
> is supposed to be thread safe. Wouldn't this in effect be treated by
> the
> CFAS as read locked
> pointer?
>
> Fred
>
> ----- Original Message -----
> From: "Scott Talsma" <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Monday, August 28, 2000 9:42 AM
> Subject: RE: No more need for cflock!!
>
> > I too believe that
> >
> > <cfset request.app = application.requestapp>
> >
> > only sets a pointer. My question regards when do we need to set
> read
> locks?
> >
> > When all application data resides in the database, and we
> establish that
> > application variables will only take on these values (and that no
> other
> > application variables will exists), then doesn't there exist an
> implicit
> > guarantee that (outside of Steve's code) only reads from the
> request
> > variable (a pointer to the application variables) will take place?
> Is
> there
> > any danger when two threads simultanously read from the same
> memory
> address?
> >
> > -----Original Message-----
> > From: Cameron Childress [mailto:[EMAIL PROTECTED]]
> > Sent: Montag, 28. August 2000 15:33
> > To: [EMAIL PROTECTED]
> > Subject: RE: No more need for cflock!!
> >
> >
> > Steve... We've been using this technique for some time now. I
> see that
> you
> > are traveling down same path now, so here are comments on what
> I've found
> by
> > doing this so far...
> >
> > One mistake I made early on was code similar to this line from
> your code
> > below:
> >
> > <cfset request.app=application.requestapp>
> >
> > I believe that this actually only creates a pointer to your
> application
> > struct, so when you call something in 'request.app', it's still
> technically
> > accessing data in your application scope, and could still lead to
> memory
> > issues without a lock. You can solve the problem by doing this
> instead:
> >
> > <cfset request.app= Duplicate(application.requestapp)>
> >
> > Also, I am very concerned about the effect of this method on a
> site which
> > stores a large amount of data in the application scope. You're
> basically
> > making CF copy the entire scope on every page call. This could
> cause
> > enormous performance problems on a large, heavy traffic site with
> alot of
> > data kept in memory.
> >
> > I've done some rudimentary load testing with this technique, and
> haven't
> yet
> > seen a serious issue with decreased performance, but as I've been
> adding
> > more and more data into the application scope for a current
> project I've
> > become more and more worried that the same test would yield
> different
> > results a second time.
> >
> > I probably will hold off on the load testing for a bit longer till
> I get
> > finished stuffing everything I need to into the application scope,
> but
> does
> > anyone else have any comments for or against this?
> >
> > -Cameron
> >
> > --------------------
> > Cameron Childress
> > McRae Communications
> > p. 770-460-7277 x.232
> > f. 770-460-0963
> >
> > > -----Original Message-----
> > > From: Steve Nelson [mailto:[EMAIL PROTECTED]]
> > > Sent: Saturday, August 26, 2000 10:34 AM
> > > To: Fusebox
> > > Subject: No more need for cflock!!
> > >
> > >
> > > I've just hit upon a technique that would mean we only ever need
> to use
> > > cflock two times in a fusebox home application. This is for
> application
> > > variables, session and server variables would need to do the
> same too i
> > > imagine (personally i never use them)
> > >
> > > First I want to propose a new filename, qry_globals.cfm the
> point of the
> > > file is to store application wide queries, it would sit in the
> root
> > > directory of your home application. It would run queries from
> the
> > > database upon booting up the server then store the variables
> into
> > > memory. This massively reduces stress on the database,
> generally it's
> > > an excellent technique. The problem has been with cflock.
> people
> > > forget to use it and CF WILL blow up on you if you forget to use
> > > CFLOCK. So I figured out a way to bypass all the cflock
> nonsense and
> > > only require two cflocks in your entire application, which do
> very small
> > > tasks.
> > >
> > > Check this code out. It's wicked cool (Hal let me know how I
> did on my
> > > fusedocs, i'm just starting to get into them, and love 'em! :)
> > >
> > > <cfsetting enablecfoutputonly="yes">
> > > <!--- qry_globals.cfm --->
> > > <!---
> > > || I start by doing a check to see if the variable
> > > application.requestapp exists if this
> > > || variable exists then I set request.app=application.requestapp
> and I
> > > do not rerun any
> > > || application wide queries. If this variable does not exist I
> rerun
> > > all the queries
> > > || and set application.requestapp=request.app
> > > ||
> > > || Then anytime I want one of these values I call it as:
> > > request.app.queryname instead
> > > || of application.queryname. By doing this I no longer need to
> use
> > > cflock in anywhere
> > > || other than this file.
> > >
> > > || [EMAIL PROTECTED]
> > >
> > > ||
> > > -->
> > > <-- request.app - this is a copy of an application variable
> called
> > > application.requestapp
> > > ++> application.requestapp - this is where all application wide
> queries
> > > sit
> > > +++
> > > --->
> > > <cfset request.maindsn="valuemusiclocal">
> > > <cfapplication name="blbl"
> > > applicationtimeout="#createtimespan(0,1,0,0)#">
> > > <cflock name="#application.applicationname#" timeout="60"
> > > type="readonly">
> > > <cfif isdefined("application.requestapp")>
> > > <cfset request.app=application.requestapp>
> > > <cfset runrequest="no">
> > > <cfelse>
> > > <cfset runrequest="yes">
> > > </cfif>
> > > </cflock>
> > > <cfif runrequest>
> > > <cfset request.app=structnew()>
> > > <cfquery name="request.app.getstates"
> > > datasource="#request.maindsn#">
> > > select * from states
> > > where active=1
> > > order by state_name
> > > </cfquery>
> > > <cfset request.app.state_rows=structnew()>
> > > <cfloop query="request.app.getstates">
> > > <cfset request.app.state_rows[state_id]=currentrow>
> > > </cfloop>
> > > <cflock name="#application.applicationname#" timeout="60"
> > > type="exclusive">
> > > <cfset application.requestapp=request.app>
> > > </cflock>
> > > </cfif>
> > > <cfsetting enablecfoutputonly="no">
> > >
> > >
> > >
> > >
> > >
> > > <!--- dsp_address.cfm --->
> > > <!---
> > > || I'm demonstrating the use of a request.app variable, note
> that
> > > || I do not need cflock, and I do not need to rerun the
> getstates query
> > >
> > > || [EMAIL PROTECTED]
> > >
> > > ||
> > > -->
> > > <--
> > > ++> request.app.getstates - this is a query with all the states
> in it
> > > +++
> > > --->
> > > <select name="state_id">
> > > <cfoutput query="request.app.getstates">
> > > <option value="#state_id#">#state_name#
> > > </cfoutput>
> > > </select>
> > >
> > >
> > > Now that's a beautiful thing! eh?
> > >
> > > Steve
> > >
> ------------------------------------------------------------------
> > > ------------
> > > To Unsubscribe visit
> >
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
> > send a message to [EMAIL PROTECTED] with
> 'unsubscribe' in
> > the body.
> >
> >
> --------------------------------------------------------------------------
> --
> > --
> > To Unsubscribe visit
> >
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
> > send a message to [EMAIL PROTECTED] with
> 'unsubscribe' in
> > the body.
> >
> >
> --------------------------------------------------------------------------
> --
> > --
> > To Unsubscribe visit
> >
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
> > send a message to [EMAIL PROTECTED] with
> 'unsubscribe' in
> > the body.
> >
> >
> --------------------------------------------------------------------------
> ----
> > To Unsubscribe visit
>
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
> send a message to [EMAIL PROTECTED] with
> 'unsubscribe' in
> the body.
> >
>
>
> ----------------------------------------------------------------------------
> --
> To Unsubscribe visit
> http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or
> send a message to [EMAIL PROTECTED] with 'unsubscribe' in
> the body.
> ------------------------------------------------------------------------------
> To Unsubscribe visit
>http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or send a
>message to [EMAIL PROTECTED] with 'unsubscribe' in the body.
------------------------------------------------------------------------------
To Unsubscribe visit
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/fusebox or send a
message to [EMAIL PROTECTED] with 'unsubscribe' in the body.