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