Ticket #420 (new defect) — at Initial Version

Opened 15 years ago

Last modified 15 years ago

Performance issue with XMLModuleLoader

Reported by: cfjedimaster Owned by:
Priority: normal Milestone: 3.2
Version: 3.1.299 Severity: normal
Keywords: Cc:

Description

I believe I sent in a message about this a few months ago, but it hit us again at work so I thought I'd check back. I believe there is a serious MG issue when your application has a mapping that points to a large set of CFCs. By that I mean - our application has one mapping, migration, that points to a folder w/ thousands of files. When I last found this issue, I noticed that CFC creation was hella slow because createObject tried to scan the folder. What I found today seems related.

So - here are the details.

XMLModuleLoader has a method, loadEventHandlers, that loads up your event handlers. Here is a loop that comprises most of the logic.

<cftry>

<cflog file="timer" text="trying to load

#ehXml.xmlAttributes.name#/#ehXml.xmlAttributes.type# xml #isXmlTypeList#">

<!--- If the event-handler already exists, get a reference to it ---> <cfif modelglue.hasEventHandler(ehXml.xmlAttributes.name)>

<cflog file="timer" text="The EH already existed. Woot."> <cfset ehInst = modelglue.getEventHandler(ehXml.xmlAttributes.name) />

<!--- If it's not an "extensible" event-handler, create a new eh object---> <cfif not ehInst.extensible>

<cfset ehInst = ehFactory.create("EventHandler?") />

</cfif>

<!--- Otherwise, try to instantiate the type. ---> <cfelse>

<cflog file="timer" text="Going to try to make it:

#serializejson(getmetadata(ehfactory))#">

<cfset ehInst = ehFactory.create(ehXml.xmlAttributes.type) >

</cfif> <!--- If the type is not found, force a base EventHandler? to be created ---> <cfcatch>

<cflog file="timer" text="I had to make a base EH"> <cfset ehInst = ehFactory.create("EventHandler?") />

</cfcatch>

</cftry>

Obviously the logs are mine. For each EH, it will attempt to create it if it doesn't exist. It uses ehFactory. If an error occurs, the catch is thrown and a base is used.

I noticed that when my XML had 20 events, all using ONE event type called generic, that MG took 4-5 seconds for every single event. It never noticed the fact that a) generic was XML, not a CFC and that b) it tried to load it and failed anyway. It constantly tried to reload the exact same type every time. What's odd is - prior to this, there is code to see if it is an XML type:

<cfif structKeyExists(variables.eventTypes, ehXml.xmlAttributes.type)

or find(",", ehXml.xmlAttributes.type)

>

<cfset isXmlTypeList = "true" />

</cfif>

So I modified that try/catch branch like so:

<cftry>

<cflog file="timer" text="trying to load

#ehXml.xmlAttributes.name#/#ehXml.xmlAttributes.type# xml #isXmlTypeList#">

<!--- If the event-handler already exists, get a reference to it ---> <cfif modelglue.hasEventHandler(ehXml.xmlAttributes.name)>

<cflog file="timer" text="The EH already existed. Woot."> <cfset ehInst = modelglue.getEventHandler(ehXml.xmlAttributes.name) />

<!--- If it's not an "extensible" event-handler, create a new eh object---> <cfif not ehInst.extensible>

<cfset ehInst = ehFactory.create("EventHandler?") />

</cfif>

<!--- Otherwise, try to instantiate the type. ---> <cfelseif not isXmlTypeList>

<cflog file="timer" text="Going to try to make it:

#serializejson(getmetadata(ehfactory))#">

<cfset ehInst = ehFactory.create(ehXml.xmlAttributes.type) >

<cfelse>

<cfset ehInst = ehFactory.create("EventHandler?") />

</cfif> <!--- If the type is not found, force a base EventHandler? to be created ---> <cfcatch>

<cflog file="timer" text="I had to make a base EH"> <cfset ehInst = ehFactory.create("EventHandler?") />

</cfcatch>

</cftry>

Notice the new cfelseif? When I did this loading went from around 1.5 minutes to about 15 seconds.

Note: See TracTickets for help on using tickets.