[CB 3.5.2 DEV] Concurrency Issues

With the dev version of CB 3.5.2 one big concurrency issues is fixed already, but i was still getting exceptions every once in a while. While these errors are very rare, it was really hard to find the cause, but i think i found it now:

the problem is in Injector.getInstance (line 207)… it checks whether a mapping is already defined for particular instanciation path and if not creates it, but i was getting different errors and i think they all have the same cause

  • Invalid Construction Type
  • Empty instanciation path when executing getComponentMetaData
  • missing constructor arguments when using the constructor injection method

so, sometimes one thread is working with a broken mapping object, where different attributes where missing/not set. Every mapping is created through registerNewInstance in the Injector, which is locked, what generally should prevent these errors. As this code in registerNewInstance can only executed by one thread per mapping/instanciation path, the code in getInstance is not locked and it is testing whether one mapping already exists:

if( NOT instance.binder.mappingExists(arguments.name) ) -> Inector.cfc line 229

but this is not enough, if the thread that executes the locked part in registerNewInstance creates, it also registers this empy mapping in the binder. All properties like type, path are set AFTERWARDS. So if another threads checks if the instance exists right at the time between creating the mapping and setting the properties, it will work on a broken mapping and cause different exceptions like mentioned above.

To fix this i added another flag to the mapping, which i called mappingComplete, what is initally set to false. then i added the following code to injector before line 229:

if(instance.binder.mappingExists(arguments.name)) {
mapping = instance.binder.getMapping( arguments.name );
mappingComplete = mapping.isMappingComplete();
}

and changed line 229 to:

if( NOT instance.binder.mappingExists(arguments.name) OR NOT mappingComplete )

and at last i set mappingComplete to true in Injector.registerNewInstance right before the mapping is returned. This makes sure, that every request will run into the lock of registerNewInstance until the first thread has completely setup the mapping.

i am currently running the test again to provoke the exceptions, but everything is fine until now.

Any feedback on this is appreciated.

best regards

Hello ColdBox-Team,

i really would appreciate if this fix is included in the final 3.5.2 release of coldbox. So, can anyone confirm that it will be included?

Ok, thanks. I posted a workaround to the concurrency issue and all tests are a go.

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

Yeah, much better and less invasive than my fix :smiley: