Ticket #420 (assigned defect)

Opened 15 years ago

Last modified 15 years ago

Performance issue with XMLModuleLoader

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

Description (last modified by boomfish) (diff)

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.

Change History

Changed 15 years ago by boomfish

  • owner set to boomfish
  • status changed from new to assigned
  • description modified (diff)
Note: See TracTickets for help on using tickets.