Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrency and scoping issues when CFM is included from within a CFC

I am placing a component in my application scope so that it is shared across all requests and it includes a a cfm template:

<cfcomponent output="false">

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = false/>

        <cftry>
            <cfinclude template="inc.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

The template that is being included simply creates an array and checks the array length is what it should be, if not it writes to the error.log file:

<cfset tmp = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp)#"/>
</cfif>

If I then run a load across it (100 concurrent threads) I get the following items appearing in my error.log file...

ERROR: element at position 3 of array variable &quot;___IMPLICITARRYSTRUCTVAR0&quot; cannot be found.
Length = 0
Length = 2

Note I'm using ColdFusion 9.0.1.274733 ontop of Java 1.7.0_09. I've tested Railo on the same JRE and it works fine.


Additional The following also causes a problem, changing the tmp variable to a struct and adding a random item in the variables scope that is not referenced anywhere...

<cfcomponent output="false">

    <!--- 
    Some random variable that does nothing with the exception
    of being the facilitator of my eternal pain
    --->
    <cfset variables.t = {}/>

    <cffunction name="run" output="false" returntype="void">

        <cfset var tmp = {}/>

        <cftry>
            <cfinclude template="inc2.cfm"/>
            <cfcatch>
                <cffile action="append"
                        file="#ExpandPath("error.log")#"
                        output="ERROR: #cfcatch.message#"/>
            </cfcatch>
        </cftry>

    </cffunction>

</cfcomponent>

Which includes a template, very similar to the first, that looks like this...

<cfset tmp.arr = [
    "one",
    "two",
    "three"
]/>
<cfif ArrayLen(tmp.arr) neq 3>
    <cffile action="append"
            file="#ExpandPath("error.log")#"
            output="Length = #ArrayLen(tmp.arr)#"/>
</cfif>

If you remove the item in the variables scope it works fine. If you dump #variables# and #local# in the template, everything is where you would expect it to be.


(Update from comments)

I've since raised this issue as a bug #3352462

like image 337
Stuart Wakefield Avatar asked Oct 24 '12 16:10

Stuart Wakefield


1 Answers

This is based on Peter's / your own comments above.

There have been / are a number of bugs with array and struct shorthand notion, and have been since CF8 introduced the syntax. Adobe's approach to fixing 'em has been a bit like whack-a-mole rather than an effort to sort the problem out once, and properly. It looks like you've found another example of this. It'd be interesting to see if this still exists in CF10 though, as I know they fixed some more during its dev cycle.

The only way around it is to not use that notation in situations in which you see these problems.

Could you pls raise a bug for this so Adobe are aware of it?

Also slightly noteworthy, but unrelated to your specific issue here: CF ain't supported on Java 1.7 yet. You might wanna bear that in mind.

like image 183
Adam Cameron Avatar answered Oct 02 '22 05:10

Adam Cameron