TransferORM / transfer

ColdFusion ORM library created by Mark Mandel, updated by @ghidinelli
Other
5 stars 3 forks source link

Element AFTERDELETEOBSERVERCOLLECTION is undefined in a CFML structure referenced as part of an expression. #7

Open ghidinelli opened 10 years ago

ghidinelli commented 10 years ago

I see the following sporadic errors (presumably under load):

The stack trace is roughly the same in AbstractBaseFacade.cfc:

/var/www/pukka/shared-prod1/transfer/com/facade/AbstractBaseFacade.cfc (188, ??)
/var/www/pukka/shared-prod1/transfer/com/facade/AbstractBaseFacade.cfc (224, CF_UDFMETHOD)
/var/www/pukka/shared-prod1/transfer/com/events/EventManager.cfc (304, CF_TEMPLATEPROXY)
/var/www/pukka/shared-prod1/transfer/com/events/EventManager.cfc (275, CF_UDFMETHOD)
/var/www/pukka/shared-prod1/transfer/com/events/EventManager.cfc (97, CF_UDFMETHOD)
/var/www/pukka/shared-prod1/transfer/com/Transfer.cfc (850, CF_TEMPLATEPROXY)
/var/www/pukka/shared-prod1/transfer/com/Transfer.cfc (684, CF_UDFMETHOD)
/var/www/pukka/shared-prod1/transfer/com/Transfer.cfc (123, CF_UDFMETHOD)
/var/www/pukka/shared-prod1/model/event/packageGateway.cfc (52, CF_TEMPLATEPROXY)

It would appear despite the double lock for setting the observer:

<cffunction name="getAfterCreateObserverCollection" access="public" returntype="transfer.com.events.collections.AbstractBaseObserverCollection" output="false">
    <cfargument name="class" hint="the class in question" type="string" required="Yes">
    <cfif NOT hasAfterCreateObserverCollection(argumentCollection=arguments)>
        <cflock name="transfer.facade.getAfterCreateObserverCollection.#getScopeIdentityHashCode()#" timeout="60" throwontimeout="true">
            <cfif NOT hasAfterCreateObserverCollection(argumentCollection=arguments)>
                <cfset setAfterCreateObserverCollection(createObservable("AfterCreateObserverCollection"), arguments.class)>
            </cfif>
        </cflock>
    </cfif>
    <cfreturn getScopePlace(argumentCollection=arguments).AfterCreateObserverCollection />
</cffunction>

That the AfterCreateObserverCollection is destroyed between the time the lock is released and the time it tries to access it?

I'm going to attempt to resolve this by returning the observer inside the lock:

<cffunction name="getAfterCreateObserverCollection" access="public" returntype="transfer.com.events.collections.AbstractBaseObserverCollection" output="false">
    <cfargument name="class" hint="the class in question" type="string" required="Yes">
    <cfif NOT hasAfterCreateObserverCollection(argumentCollection=arguments)>
        <cflock name="transfer.facade.getAfterCreateObserverCollection.#getScopeIdentityHashCode()#" timeout="60" throwontimeout="true">
            <cfif NOT hasAfterCreateObserverCollection(argumentCollection=arguments)>
                <cfset setAfterCreateObserverCollection(createObservable("AfterCreateObserverCollection"), arguments.class)>
                <!--- adding here because under load, we occasionally get errors between the time we release the lock and the time we run getScopePlace() at the end of the method --->
                <cfreturn getScopePlace(argumentCollection=arguments).AfterCreateObserverCollection />
            </cfif>
        </cflock>
    </cfif>
    <cfreturn getScopePlace(argumentCollection=arguments).AfterCreateObserverCollection />
</cffunction>
ghidinelli commented 10 years ago

Pull request #8 - will test in production to see if it cures the problem.