I apologize for bringing back an old topic, but I have a specific question.
I've only been using CF for a few months, so the answer to this may be quite
simple/obvious.
I've used the attached logic in an application that only uses application
variables and it works perfectly. I'm now working on a new application that
needs to keep track of a user's authorization level. I'm doing this by
using a session variable, session.authLevel. If that variable doesn't
exist, I ask the user to log in (fuseaction=showLogin), and if they are
successful (fuseaction=attemptLogin) I set the session variable.
I also need to make sure that the application will work without cookies, so
I need to pass CFID and CFTOKEN on each URL. Currently I'm doing this with
session.urlToken. This means that I need to read session.urlToken on every
page, so I need a read-only lock for that. As mentioned above, I need to
set session.authLevel after the user logs in, so I need an exclusive lock
for that.
I tried using the logic below to wrap my cfswitch statement in a read-only
SESSION lock, but that prevents me from obtaining the exclusive lock that I
need to set session.authLevel.
So I'm just wondering what the best way to deal with this is, other than
placing a read-only lock in each page. I noticed a few people saying that
they never use session variables. How do you deal with user authorizations
if you're not using them? Do you just use client variables instead, or is
there a better trick that I'm totally missing?
If anyone has any comments on how I might do the above better (including
managing sessions without cookies), please let me know.
Thanks,
Bob Silverberg
[EMAIL PROTECTED]
-----Original Message-----
From: BOROVOY Noam [mailto:[EMAIL PROTECTED]]
Sent: Monday, August 28, 2000 11:18 AM
To: [EMAIL PROTECTED]
Subject: RE: No more need for cflock!!
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.