• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

application scope locking and caching of CFC's (pulling my hair out!)

New Here ,
Aug 10, 2009 Aug 10, 2009

Copy link to clipboard

Copied

Hi,

I have 2 CFC's that I have written for a flex based app, 1 is a cache manager to store CFC's in the application scope, the other is something called voFactory.cfc, which will take a query object or structure, and convert it into an array of typed objects for flex.  I need to find out where locking would be appropriate here, btw- this is CF 8.

the line in red bold is throwing an error- trying to reference elements in the metadata of a CFC that should exist, but for some reason don't.  The error is always something like:

The element at position 19 of dimension 1, of array variable "PROPERTYARRAY," cannot be found.

The element is random though as is the error, there is nothing distinct about where it throws the error, so I'm thinking race condition of some sort.

Here are examples of how they get called in code, followed by snippets of the code,

<cfreturn application.voFactory.query2ValueObjects(qGetEvents,'vo.EventVO') />

and

<cfset dataStruct.CLIENTLIST = application.cacheManager.getComponent("clients").getClientList()>

the two CFCs rely on each other, the voFactory pulls the value object CFCs from the application scope cache.

onApplicationStart() code:

<cfset application.voFactory = createObject("component","API.system.voFactory").init()>
<cfset application.cacheManager = createObject("component","API.system.CacheManager").init()>

Here is relevant part of the cache manager:

<cffunction name="getComponent" access="public">
        <cfargument name="componentName" type="string" required="true">
       
        <!--- If it exists in cache, retrieve else create --->
        <cfif not structKeyExists(this.componentList,arguments.componentName)>
            <cfset this.componentList[arguments.componentName] = createObject("component",'API.' & arguments.componentName)>
        </cfif>
       
        <cfreturn this.componentList[arguments.componentName]>
    </cffunction>

And the voFactory cfc

<cffunction name="query2ValueObjects" hint="Converts a query to array of value objects" access="public" returntype="array" output="false">
        <cfargument name="queryObject" type="query" required="true">
        <cfargument name="valueObjectPath" type="string" required="true">
       
        <cfset var path = ''>
        <cfset var propertyArray = ''>
        <cfset var tVO = ''>
        <cfset var loopQuery = ''>
        <cfset var property = ''>
        <cfset var returnArray = ''>
       
        <cfset loopQuery = arguments.queryObject>
        <cfset path = arguments.valueObjectPath>

<!--- I GET THE PROPERTIES OF THE VO, LOOP OVER THEM TO CREATE TYPED OBJECTS --->
        <cfset propertyArray = GetMetaData(application.cacheManager.getComponent(path)).properties>
        <cfset returnArray = arrayNew(1)>
       
        <cfloop query="loopQuery">
            <cfset tVO = structNew()>
            <cfset tVO['__type__'] = 'API.' & arguments.valueObjectPath>

            <cfloop from="1" to="#ArrayLen(propertyArray)#" index="property">
                <cftry>

<!--- ONLY USE SCALAR VALUES --->
                    <cfif propertyArray[property].TYPE EQ 'string' OR propertyArray[property].TYPE EQ 'numeric' OR propertyArray[property].TYPE EQ 'date'>
                       <cfset tVO[propertyArray[property].NAME] = loopQuery[propertyArray[property].NAME][loopQuery.CurrentRow]>
                    </cfif>
                    <cfcatch>

     <!--- debug code --->

                        <cfrethrow>
                    </cfcatch>
                </cftry>
            </cfloop>
           
            <cfset arrayAppend(returnArray,duplicate(tVO))>
        </cfloop>
       
        <cfreturn returnArray>
    </cffunction

TOPICS
Advanced techniques

Views

1.1K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Aug 10, 2009 Aug 10, 2009

Copy link to clipboard

Copied

Without reviewing any of the logic, I noticed the loopQuery variable is not var scoped.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Aug 10, 2009 Aug 10, 2009

Copy link to clipboard

Copied

thanks for looking at it, but loopQuery is var scoped, it's the 4th var at the top of the function.

d.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Aug 10, 2009 Aug 10, 2009

Copy link to clipboard

Copied

You are correct. My bad.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Aug 11, 2009 Aug 11, 2009

Copy link to clipboard

Copied

LATEST

It might help to initialize the array right after you define it, something like this

<!--- Define array --->
<cfset var propertyArray=arrayNew(1)>
<!--- Initialization: array expected to hold at least 20 structures --->
<cfset temp = ArraySet(propertyArray, 1,20, structNew())>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation