[CB 3.5] Proxy Request Concurrency Problems

There’s a pretty serious problem with the handling of proxy requests.

When making requests to the same “endpoint” within a very narrow window of time, Flex automatically joins the “requests” in a single network call.

At which point, the way they are executed with ColdBox causes a shared RequestContext between both requests. Which is fine as long as there are no collisions, but in my case this is causing a TON of problems.

So, I’m completely game for making a fix and submitting a patch, but I’m not sure where/how to tackle this.

I’m thinking that somewhere in ColdBoxProxy.process(), we ensure that the RCs are isolated somehow. My initial thought was some sort of new thread for each specific request, but unfortunately, you don’t have access to any scope beyond THREAD. So this won’t work.

Luis, I’d really love your advice on this. As I said above, I will make the fix and submit it back via a pull request.

If anyone would like clarification on this, please let me know!

-Ben

Okay, in a moment of clarity, I added a line to ColdBoxProxy to force the creation of a new request context for each event run with ‘process’.

structDelete(request,“cb_requestContext”);

Perhaps it’s best to make this an optional behavior by passing in an argument for ‘newRequestContext’?

Thoughts?
Ben

I agree with you but I cannot change the way flex bundles calls. Do they even add an Id to distinguish? They must as they need I identify what to return right?

I played around with changes to Flex, but short of changing the way flex makes requests by rewriting the core RemoteObject class,mthernisnt a clean way to do this. I think my change (which I’ve already submitted a pull request for) is a better solution.

It does make the assumption that you want each request/procedure-call to operate independently (ie, as a distinct requests with its own RC). However I added a parameter to “process” to alow the treatment of the RPCs as a single request. So, the expected behavior works fine and the fringe use case is accounted for.

Well, not sure why this would solve your issue as you are recreating the context, so if requests are bundled, they still share it or might override each other as they share the same request?

signature0.jpg

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 that, though the events are “processed” sequentially, when bundled together in one network request (as Flex is built to do) the RequestContext is currently shared between ‘process’ calls performed by the proxy.

So, if two RPCs are present in a single network request from Flex, the second request is inheriting a “dirty” request context which can have a ton of implications. Just imagine I have ‘login’ and ‘deleteUser’ that both get called in a same request, if I have ‘rc.user’ that is set in my login proxy call, then in my deleteUser call, I could be deleting the wrong user.

In the vast majority of cases this won’t cause a problem, but it’s distinctly possible to have a very nasty problem that arises out of the shared RC, especially since that isn’t the expected behavior.

So, my “fix” just ensures that each time ‘process’ is called, the RC is clean and only populated during the normal execution of that event (and anything it triggers).

Here’s an example of where this caused me problems. I have a proxy method that has an optional parameter, siteID. With no default value. In a separate proxy method, I purposely set the siteID value. So, when these two are bundled together in one network request, the siteID might be present in the RC when executing that first event and behave differently than if the RC had been clean.

The short of the long is that, however it’s done, the ‘process’ method should stand up a new RC by default when it’s called. The full ‘request’ lifecycle happens during a process and as such, the RC should be effectively torn down/set up each time it’s run.

Thoughts? comments? agreement? disagreement?

-Ben

signature0.jpg

Yea, but that is what I don’t get. If Flex bundles your requests, you still share a request scope right? But they fire sequentially, so one bundled request creates a new rc, does it mean that it has to end as well, before the other one fires?

I guess my problem is reproducing what Flex does. But if that works for you, then good :slight_smile:

I just added a removeContext() method to the request service.

signature0.jpg

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

signature0.jpg