Hi Sean,
> Depends. First off, you do not necessarily have to lock
> access. You don't need locking for data integrity - only for
> race conditions. And a lot depends on how you want your CFC
> to behave. If a CFC is stateless (has no data in "this" scope
> or "variables" scope) then you don't need to lock. If a CFC
> is stateful (uses "this" scope or "variables" scope) then you
> probably shouldn't store it in "server" scope anyway -
> "session" or "request" scope would make more sense.
I know there are no race conditions in this case, but it just doesn't feel
right not locking in this case as its ONE object I create and let many
requests from many applications use it (that's the idea anyway).
> In your case, it looks like you have a stateful CFC that
> needs to behave like a "request" scope variable since you're
> storing per-request data as far as I can see.
>
> In other words, your business logic mostly precludes any
> savings you might get by trying to only instantiate the CFC
> once - because you need a separate instance for every request
> anyway I think! However, see below for how I've reworked your code...
I was thinking I need a separate instance or lock it, I choose to lock it,
as I feel creating a new instance each time is much more resource hogging,
since I want almost every request to use this object. But I could be wrong
of course, as I said I am not completely comfortable with this approach.
> > request.result.objError.fnConstruct(
> > request.result );
> > request.result.objError.fnDisplay( request.result
> > );
>
> This certainly does look a bit odd. When you construct the
> error object (and please use 'init()' for your constructor
> for consistency with how everyone else seems to be doing it!
> :) you could pass in the 'result' object and the error object
> should remember it - so you don't need to pass it in again on
> subsequent calls.
I was thinking about using init() but just because everyone else is using it
did not seem like a good reason enough ;-))
> > But I can't really
> > tell you why, but I'm pretty sure its not a good thing
> having to pass itself
> > back with request.result
>
> Your gut feeling is correct. Only if the error object were a
> stateless service would this be expected behavior.
>
> > <cflock
>
> You don't need cflock if fnExecute() is stateless. (Why do
> you have 'fn' as a prefix? It makes the code hard to read -
> and it's obviously a function because you're calling it!)
I have fn as a prefix because it's the naming convention I use for
JavaScript, SQL and CF - I just like to stick to it, makes it very easy to
read, within in one glance I see the object and function..
> > request.result =
> > server.objProcess.fnExecute( "this string means nothing"
> > );
> > request.result.objError.fnConstruct( request.result
> > );
>
> If fnExecute() returns a struct with a fully constructed
> error object, it really should pass the struct into the error
> object at construction so the calling code doesn't have to do
> that (i.e., fnExecute() should call fnConstruct() - or rather
> init() - on the error object in the returned struct). Make sense?
Sorry my sample did not fully show what I wanted to get to in the end, error
construct should not be called on execution of every process, it should be
called after for example;
if ( request.result.error.isError )
{
request.result.objError.fnConstruct()
}
onRequestEnd.cfm
Something like
if ( request.result.error.isError AND NOT request.result.error.isDisplayed )
{
request.result.objError.fnDisplay()
}
So we know what I am doing wrong, and that is that I am passing the struct
back into it, but the object should really refer to the struct as this (or
not), but how to accomplish this?
> > request.result.objError.fnDisplay( request.result
> > );
>
> See above. This code probably ought to look like this instead:
>
> request.result = server.process.execute( "blah" );
> request.result.error.display();
Yes yes! It should... How..?
> execute() creates the struct, populates the error member with
> a fully-constructed error object like this:
>
> result.error = createObject(...).init( result );
> return result;
>
> The error object's init() method does this to remember the
> enclosing struct:
>
> variables.parent = arguments.parent;
This is where I start to lose you unfortunately, I read it a couple of times
but my brain just won't grasp the concept you are trying to explain, would a
sample with my code be to much to ask for??
> The error object's display() method refers to
> variables.parent for the enclosing struct.
>
> > this.result =
> > structNew();
>
> Don't use "this" scope - public data is a Bad Thing(tm)!
> Encapsulate it - use "variables" scope and provide get / set
> methods if necessary.
Definitaly lost you here, I want to understand though. I'm a bit of a visual
person ;-((
> Having said that, the process object should probably be
> stateless anyway and not use "this" scope or "variables" scope at all.
>
> > <cffunction
> > access="public"
> > name="fnExecute"
> > output="false"
> >
> > returntype="struct">
> ...
> > <cfset structUpdate(this.result.error,
> >"isError", true)>
> > <!--- Append the error
> > message --->
> > <cfset
> > this.result.objError.fnAppend( this.result, 'this is the message '
> > )>
>
> Use a local variable for the result struct instead of "this" scope:
>
> <cfset var result = structNew() />
Would that not recreate the whole object we created in the first step?
I'll have a play with it hoping it will all make sense, I appreciate your
efforts...
Cheers,
Taco
>
> (at the top of the execute() function).
>
> Now your process is stateless and can live in "server" scope.
>
> Hope that helps / makes sense?
>
> ---
> You are currently subscribed to cfaussie as:
> [EMAIL PROTECTED] To unsubscribe send a blank email to
> [EMAIL PROTECTED]
> Aussie Macromedia Developers: http://lists.daemon.com.au/
>
---
You are currently subscribed to cfaussie as: [EMAIL PROTECTED]
To unsubscribe send a blank email to [EMAIL PROTECTED]
Aussie Macromedia Developers: http://lists.daemon.com.au/