[ColdBox 3.5.1] Wirebox and concurrent requests

Hi Guys,

I think I have a problem with concurrency in wirebox. I am executing 3 requests to different event handlers at the same time and I am getting randomly the error

Error Messages: The ‘’ name is not a valid component or interface name.
Component and interface names cannot be empty and cannot start or end with a period.

coldbox\system\ioc\config\Mapping.cfc, line 578

As this message is not really helpful i was putting some logs in the ioc/config/Mapping.cfc and ioc/Injector.cfc to investigate the problem…

“Information”,“web-17”,“06/05/12”,“10:29:02”,“Injector.cfc:217 coldbox.system.EventHandler”
“Information”,“web-13”,“06/05/12”,“10:29:02”,“Injector.cfc:217 coldbox.system.EventHandler”
“Information”,“web-13”,“06/05/12”,“10:29:02”,“Injector.cfc:217 StorageManager.handlers.Group”
“Information”,“web-17”,“06/05/12”,“10:29:02”,“Injector.cfc:217 StorageManager.handlers.Location”
“Information”,“web-17”,“06/05/12”,“10:29:02”,"Injector.cfc:252 StorageManager.handlers.Location, " // (logging mapping.getName, mapping.getPath)
“Information”,“web-13”,“06/05/12”,“10:29:02”,“Injector.cfc:252 StorageManager.handlers.Group, StorageManager.handlers.Location” // (logging mapping.getName, mapping.getPath)
“Information”,“web-17”,“06/05/12”,“10:29:02”,"Mapping.cfc:577 StorageManager.handlers.Location, , " // (logging getName() , getPath() , instance.path)
“Information”,“web-13”,“06/05/12”,“10:29:02”,“Mapping.cfc:577 StorageManager.handlers.Group, StorageManager.handlers.Location, StorageManager.handlers.Location” // (logging getName() , getPath() , instance.path)

wirebox mixes up the mappings, so that the request to the Location handler finishes with that error and the request to the Group handler returns the results of the location handler. This problem also applies for CB 3.5, but it is less often. Hope somebody can help me fix this problem.

best regards

I’m having a hard time figuring out where that error is actually happening. Can you please provide a full stack trace for the error?

At first glance, it seems that the same mapping object is being processed by two different requests. Is this error happening on your dev or production environment?

Thanks!

~Brad

I’m encountering the same issue. It seems to occur whenever I reinitialize, because once the errors stop, they don’t happen again until I reinitialize. Sometimes, simply reiniting again will fix it, but other times it doesn’t.

In addition to the “the ‘’ name is not a valid component or interface name” error, I also receive this one: “The method _actionExists was not found in component xxxxxx”.

In my situation, I have a bunch of Ajax requests that fire off at about the same time. Interestingly, if I copy the url of one of the failed requests, load it in a new tab, I can recreate the error (only 1 request). However, if I reinit, go back to the new tab, and reload, the response comes back as expected with no error.

Right now, I don’t have any code in production, so this is currently a dev issue. I’ve messed around with the CB settings quite a bit, but none of the configurations I’ve used seem to make a noticeable difference.

are you using singleton reload? or config auto reload?

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

Ok, so I just set handlersIndexAutoReload to true, and the issue has disappeared. That’s good news for dev :slight_smile:

When I move to production, though, the docs say that this should be set to false. Is there a way to mitigate this if and when the prod environment gets reinited?

Thanks

auto reload should be false for production. So not sure what is going on with that. What about the other settings.

Also, remember. A reinit is a hard RESET of the internal structures. A zero error reinit is NEVER guaranteed. There might be 100 concurrent requests at the server level and you are stopping them hard in their tracks. Reinit is a last resource to have in production environments.

If you want to gracefully restart, then we would recommend using something like a Deploy Interceptor that sends an applicationstop() signal at request end, so things gracefully restart

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

Here are my settings for dev:

coldbox.handlerCaching = false;
coldbox.eventCaching = false;
coldbox.handlersIndexAutoReload = true;
wirebox.singletonReload = false;
configAutoReload= false;

I’ll take a look into the deploy interceptor idea–thanks!

@joel

the setting is not the problem and the problem is not the reinit… the problem is the construction of the handlers…

we are talking about simultaneously requests to different handlers that are not constructed and get first constructed during this request by wirebox and with a specific timing the mappings get messed up and the function getPath in the mapping returns an empty string which throws the error when calling getComponentMetaData with this empty string and to make it worse the other handler gets the path and returns wrong results… it is not during fwreinit… the mapping itself is not the problem but the discovery of the instantiation path CAN mix up the path’s

ok to make it a little bit clearer i refer to my logs on the first post

request1 to handler Group -> starts thread web-13 -> wirebox tries to discover the handler instantiation path finds it but somehow adds it to the mapping of the other thread
request2 to handler Location -> starts thread web-17 -> wirebox also tries the discovering but gets the path set of the other thread

the processing of the mapping for handler Group fails and throws the described error and the mapping of handler Location instantiates the handler Group and returns the wrong results and i guess it succeeds because both requested functions have the same name

maybe it’s not the fault of wirebox at all, but after the discovery of the instantiation path’s the mappings are wrong and this is reproducable, but not debuggable, because there are 2 threads involved

i will investigate this further, cause i really love coldbox and definitely want to use it :slight_smile:

Yea, if this was the case, no application would work at al. So something is amiss here.

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

the problem is a timing issue not wirebox in general, reinit and fire ajax calls simultaneously to different handlers, and after some tries you will receive that error

I did some further investigations in the sourcecode and i think i figured out the problem. The problem is the binder… let’s start in Injector.cfc at line 341 which is the function registerNewInstance

it wants to create a new mapping via the binder ( map(name).to(path) )… because the binder needs a reference on the mapping between different calls it keeps this mapping as currentMapping in variables scope, but since this is surrounded by cflock, there should be no problem with concurrency… but after the binding and after the cflock it returns with instance.binder.with( arguments.name ) line 352 in Injector.cfc and if you have a look in the with method of Binder.cfc in line 461 you will see that the currentMapping is set to the alias given by the parameter, so with bad timing the problem i explained in the beginning of this thread occurs, because it can happen that the binder works on the wrong mapping reference.

i have a addition to make… as the before mentioned seems to me to still be a problem, i found also another issue. when looking in the docs for cflock, i found that a lock is only exclusive for its name, but every discovery of a handler has its own lock name and therefor i think registerNewInstance in Injector.cfc line 341 is not threadsafe, because the binder is always working on currentMapping as class member and the lock is not exclusive for all threads but only for threads who want to build the same component, the lock name should be changed from “Injector.RegisterNewInstance.#hash(arguments.instancePath)#” to “Injector.RegisterNewInstance” to make the binder threadsafe for all threads.

furthermore i commented out the setting of currentMapping in the with method of Binder.cfc in line 461, but i am not sure if this still is a problem or not. hope to hear some opinions form the community

best regads

Thanks Phal,

Will look into this.

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

Phal,

I did an update for the concurrency issues. Can you verify please. It is on the development branch. This is targeted for a 3.5.2 release most likely to be released soon as they are some critical fixes.

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

Hi Luis,

thanks for the fast changes, i can try it on monday, but i was looking in your last commit and you only changed one issue. In my opinion the name of the lock is the bigger issue what is causing the mapping problems.

"Injector.RegisterNewInstance.#hash(arguments.instancePath)#" to "Injector.RegisterNewInstance"

what do you think?

Not anymore as only the creation of named mapping needs to be looked. The pointer is not used anymore and I don’t want to lock the entire acces to the binder when in reality all I need is a new mapping to be created.

And what’s even stranger is that despite it passing the wrong argument as the view to be rendered in the layout it’s also trying to find that incorrect layout within the local app views folder when in 3.1 this is using the external layouts and views location.

Nolan Dubeau

Load .,8,1

Ah yeah you’re right. I’ll test on monday.

best regards

I tested the development branch and it seems to be fixed. I could not reproduce the error. Thanks again Luis for the fast patch.

Best Regards

I tried this out against the configuration that was giving me issues before. It seems to now be working as expected. Thanks!