Can anyone help me get my head around this use case?

11 views
Skip to first unread message

Adam

unread,
Feb 24, 2009, 8:31:57 AM2/24/09
to edmund-coldfusion
Ok..so I started playing with Edmund on Monday night!

My Deal:
I have a custom "factory" object which gets loaded up by coldspring
for each of my applications....
The factory creates/gets abstract services for ORM objects. Actually,
it's quite similar to approaches taken in Metro (metro.riaforge.org),
These services are composed of a gateway, and a TIBO...defined for
each class in a package, per application... The factory will cache
objects after creation and then get() them from internal cache with
each request there after.

My Need:
On appInit.. I want Edmund to fire async events to have my factory
load each object for each defined "class" in each "package" of my
applications...

This might accomplish two things for me
1. In larger apps, it could server as a way to test the loads on my
servers when the app is creating/getting every required object, or in
effect, pre-loading the objects that would otherwise be created on the
first request for said object...

2. It could even improve performance with smaller apps by effectively
loading up into factory cache all required services on AppInit instead
of on a specific request.


My Code...

<!--- MVC Handler: Main.cfc --->
<cffunction name="onAppInit" access="public" returntype="void"
output="false">
<cfargument name="Event" type="any">
<!--- ON Application Start Here --->
<cfset var eventValues = structNew()/>
<cfset loadEdmund()/>

<cfset logEvent(message="Begin Loading
Application",logFile="application")>

<cfset getMajikFactory().loadPackages()/>
<cfset eventValues['MajikFactory'] = getMajikFactory()/>

<cfif getController().settingExists("MajikSettings.PreloadMajikLayer")
>
<cfif getController().getSetting
("MajikSettings.PreloadMajikLayer",false) >
<cfset logEvent(message="Loading Majik
Packages....",logFile="application")>
<cfset dispatchEvent("LoadMajikPackages",getMajikFactory())/>
</cfif>
</cfif>
.
<cfset logEvent(message="Finished Loading
Application",logFile="application")>
</cffunction>

<cffunction name="dispatchEvent" returntype="void" access="private"
output="false">
<cfargument name="eventName" type="string" required="true"/>
<cfargument name="Factory" type="any" required="true"/>
<cfset getEdmund().newEvent(arguments.eventName).value
("MajikFactory",arguments.Factory).dispatch() />
</cffunction>


<!--- Edmund.xml --->
<edmund>
<listeners>
<listener name="Application"
type="majik.system.core.listener.ApplicationListener"/>
</listeners>

<controllers>
<controller name="PackageLoader"
type="majik.system.core.PackageLoader">
<message-listener message="loadPackages" function="handleEvent"
async="true" />
</controller>
</controllers>

<event-handlers>
<event-handler event="LoadMajikPackages">
<broadcasts>
<message name="loadPackages" />
</broadcasts>
</event-handler>
<event-handler event="log">
<notify listener="Application" method="logEvent" />
</event-handler>
</event-handlers>

</edmund>


<!--- PackageLoader.cfc Defined As Controller in Edmund.xml listening
for "loadPackages"--->
<cffunction name="handleEvent" returntype="boolean" access="public"
output="false" hint="I handle an event - Build Up All Package Objects
Asyncronously....">
<cfargument name="event" type="edmund.framework.Event"
required="true" hint="I am the event to be handled." />
<cfset var factory = arguments.event.value("MajikFactory")/>
<cfset var packages = factory.getPackages()/>
<cfset var objects = 0/>
<cfset var object = 0/>
<cfset var classList = 0/>
<cfset var svc = 0/>

<cfloop array="#packages#" index="package">
<cftry>
<cfset super.logEvent("Loading| #Package.name# - Package")/>
<cfset objects = package.objects/>
<cfset classList = structKeyList(objects)/>
<cfloop list="#classList#" index="object">
<cftry>
<cfset super.logEvent("=======Loading| #objects[object].name# -
Class")/>
<cfset svc = factory.getService("#package.name#.#objects
[object].name#") />
<cfcatch><cfset super.logEvent("ERROR - #cfcatch.message#")/></
cfcatch>
</cftry>
</cfloop>
<cfcatch><cfset super.logEvent("ERROR - #cfcatch.message#")/></
cfcatch>
</cftry>
</cfloop>
<cfreturn true />
</cffunction>


LOG File RESULTS
Majik:Log > eti - Begin Loading Application | {ts '2009-02-24
06:59:44'}
Majik:Log > eti - Loading Majik Packages.... | {ts '2009-02-24
06:59:44'}
Majik:Log > Loading| newsletter - Package | {ts '2009-02-24 06:59:44'}
Majik:Log > =======Loading| email - Class | {ts '2009-02-24 06:59:44'}
Majik:Log > eti - Finished Loading Application | {ts '2009-02-24
06:59:44'}
Majik:Log > =======Loading| subscriber - Class | {ts '2009-02-24
06:59:45'}
Majik:Log > =======Loading| footer - Class | {ts '2009-02-24
06:59:47'}
Majik:Log > =======Loading| link - Class | {ts '2009-02-24 06:59:47'}
Majik:Log > =======Loading| linkView - Class | {ts '2009-02-24
06:59:48'}
Majik:Log > Loading| plating - Package | {ts '2009-02-24 06:59:49'}
Majik:Log > =======Loading| department - Class | {ts '2009-02-24
06:59:49'}
Majik:Log > =======Loading| platerAssignment - Class | {ts '2009-02-24
06:59:49'}
Majik:Log > =======Loading| plater - Class | {ts '2009-02-24
06:59:50'}
Majik:Log > Loading| salesOrder - Package | {ts '2009-02-24 06:59:51'}
Majik:Log > =======Loading| lot - Class | {ts '2009-02-24 06:59:51'}
Majik:Log > =======Loading| item - Class | {ts '2009-02-24 06:59:52'}
Majik:Log > =======Loading| status - Class | {ts '2009-02-24
06:59:52'}
Majik:Log > =======Loading| order - Class | {ts '2009-02-24 06:59:53'}
Majik:Log > Loading| menu - Package | {ts '2009-02-24 06:59:53'}
Majik:Log > =======Loading| group - Class | {ts '2009-02-24 06:59:53'}
Majik:Log > =======Loading| item - Class | {ts '2009-02-24 06:59:53'}
ect. ect. ect. ect.
ect. ect. ect. ect.
ect. ect. ect. ect.

MY QUESTION(s)..
1 a) How can I set up my Factory / Event / Handlers to handle this in
a more Edmund-esq way?
b) Would child, parent, or chained events be something that makes
sense or is even usable here?
c) How can I do something where each class get loaded async rather
then in the loop i have in PackageLoader.cfc now?

2) Should I just put an "handleEvent" in my MajikFactory and subscribe
messages to that instead of in this PackageLoader.cfc. to have Edmund
call on the factory directly to load this stuff?


I know there are multiple ways of doing this in edmund and, even
though I think I have some understanding of this, I'm still having a
bit of difficulty visualizing in my head exactly how i can make the
above work in a cleaner way while utilizing more of the async
functionality available with Edmund. Getting logging and auditing
implemented using edmund yesterday was a snap... this is some pretty
tasty stuff!

So anyways, does _anybody_ even understand what I'm trying to do
here?? Maybe I'm crazy,
or maybe you are too and have something to share which could help me
sort out this one?


thanks in advance for considerations extended...

Adam Drew
Magic Ferret Solutions

Sean Corfield

unread,
Feb 24, 2009, 11:27:21 AM2/24/09
to edmund-c...@googlegroups.com
On Tue, Feb 24, 2009 at 5:31 AM, Adam <epn...@gmail.com> wrote:
> 1 a) How can I set up my Factory / Event / Handlers to handle this in
> a more Edmund-esq way?

I would recommend having each object that you want initialized in this
manner to add a listener for the event. That way, you fire the event
once and Edmund manages each object handling the event.

> b) Would child, parent, or chained events be something that makes
> sense or is even usable here?

The child/parent machinery is intended for bubbling events, i.e., once
an event is handled, the handler can opt to stop event propagation or
let Edmund pass the event to the parent "Edmund" to see if anyone in
that context wants to handle it. I don't think your scenario needs to
handle that.

I also don't think chained events are appropriate here: they can lead
to brittle, tightly-coupled code so they should only really be used
when you have a multi-step process that requires different components
to collaborate, i.e., component A handles the start of the process and
dispatches Event 2 when done so that components B and C can do their
thing and fire off events to say they're done and so on.

> c) How can I do something where each class get loaded async rather
> then in the loop i have in PackageLoader.cfc now?

Have each class act as an async listener.

> 2) Should I just put an "handleEvent" in my MajikFactory and subscribe
> messages to that instead of in this PackageLoader.cfc. to have Edmund
> call on the factory directly to load this stuff?

See answers to 1) (no).

Hope that helps (assuming I've understood you).
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

Reply all
Reply to author
Forward
0 new messages