Dan, Thanks for taking a look at this. Let me know if you need me to help out in any way. Seumas
On Fri, May 11, 2012 at 11:03 AM, Daniel Kulp <[email protected]> wrote: > > You're definitely right. Still an issue on trunk. :-( > > I'm attempting to remove the setting of the Executor in the ServiceImpl. > All the CXF tests are OK with it. I'm concerned about the TCK (not sure > why we would have set it to begin with unless the TCK required it) so I''ve > started the process of running those tests now. That takes quite a bit > longer. If it's OK, I'll get that committed. > > What's interesting is that the Camel async stuff doesn't hit this and > actually uses the workqueus. Not really sure what path it's taking to get > there, but interesting none-the-less. > > Dan > > > > On Friday, May 11, 2012 02:02:54 AM Seumas Soltysik wrote: > > Hi Dan, > > I think I found the source of the issue. > > > > The customer I have been working with noted that for async call, CXF > 2.1.x > > was behaving differently that CXF 2..3.x. > > In 2.1.x the number of threads being created to handle the response for > > async call was limited by the parameters of the AutomaticWorkQueue. The > > result was that 100 async calls would only produce a maximum of 25 > threads > > to handle the responses to the calls. > > > > Howerver, the customer noticed that for 2.3.x for 100 async invocations, > > 100 threads were being created to handle the responses. > > > > By comparing the HTTPConduit code for 2.1 to 2.3, I was able to find the > > problem. > > > > Here is the pertinent code for 2.1: > > > > WorkQueueManager mgr = > > outMessage.getExchange().get(Bus.class) > > .getExtension(WorkQueueManager.class); > > AutomaticWorkQueue queue = > > mgr.getNamedWorkQueue("http-conduit"); > > if (queue == null) { > > queue = mgr.getAutomaticWorkQueue(); > > } > > queue.execute(runnable); > > > > Here is the code for 2.3: > > > > Executor ex = > > outMessage.getExchange().get(Executor.class); > > if (ex == null) { > > WorkQueueManager mgr = > > outMessage.getExchange().get(Bus.class) > > .getExtension(WorkQueueManager.class); > > AutomaticWorkQueue qu = > > mgr.getNamedWorkQueue("http-conduit"); > > if (qu == null) { > > qu = mgr.getAutomaticWorkQueue(); > > } > > qu.execute(runnable, 5000); > > } else { > > > > outMessage.getExchange().put(Executor.class.getName() > > + ".USING_SPECIFIED", > > Boolean.TRUE); > > ex.execute(runnable); > > } > > > > As you may notice the major difference is that the first step in the 2.3 > > code is to get an Executor from the Exchange. > > > > For async calls the Executor is not null. The Executor is set in the > > ServiceImpl.createPort() code: > > > > service.setExecutor(new Executor() { > > > > public void execute(Runnable command) { > > > > Executor ex = getExecutor(); > > > > if (ex == null) { > > > > ex = OneShotAsyncExecutor.getInstance(); > > > > } > > > > ex.execute(command); > > > > } > > > > }); > > > > > > The OneShotAsyncExecutor does not throttle the thread creation which > > results in the issue mentioned above. > > > > > > By adding code like this after the creation of the proxy, the old > behavior > > is established: > > > > > > rpcperf = aRPCPerfService.getRPCPerfSoapHttpPort(); > > > > Bus bus = BusFactory.getDefaultBus(); > > > > > > WorkQueueManager mgr = bus.getExtension(WorkQueueManager.class); > > > > Executor ex = mgr.getAutomaticWorkQueue(); > > > > > > org.apache.cxf.endpoint.Client client = > > org.apache.cxf.frontend.ClientProxy.getClient(rpcperf); > > > > org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint(); > > > > cxfEndpoint.setExecutor(ex); > > > > > > Not sure what the exact fix is for this since adding the check for the > > Executor on the service seems like it might be important for setting > > custom Executors. > > > > > > By inspection, this seems to be a problem on trunk as well. > > > > > > Thoughts? > > > > > > Seumas > > > > > > > > The problem is that for async calls, this is not null by default. > > > > On Thu, Mar 29, 2012 at 3:06 PM, Daniel Kulp <[email protected]> wrote: > > > On Thursday, March 29, 2012 02:36:55 PM Seumas Soltysik wrote: > > > > It would appear at this point that each async invocation involves a > > > > listener thread, waiting for a response from the server. Is there a > > > > way > > > > > > to > > > > > > > configure the number of listener threads used by a particular client > > > > so > > > > that 100 async invocations do not result in 100 listener threads? > > > > > > The default should max out at 25 per bus. Basically, they end up on > > > the > > > "default" WorkQueue of the bus which default to a max of 25 threads. > > > You can configure the default WorkQueue to have more or less threads if > > > you want. > > > > > > There is supposed to be code to allow for a specific "http-conduit" > > > named > > > workqueue to be optionally configured, but I just noticed that code > > > isn't > > > working properly and will always re-grab the default workqueue. I'll > > > get > > > that fixed. > > > > > > You can also call the Service.setExecutor(..) prior to creating the > > > proxy > > > if > > > you want to specify a specify executor for the client. > > > > > > > I was doing some research on this issue and it appears that at some > > > > point > > > > there was some work being done in this area: > > > > > http://cxf.547215.n5.nabble.com/Async-HTTP-client-side-td2835428.html > > > > > > Never had time to really finish/pursue that more in depth. :-( > > > > > > > > > -- > > > Daniel Kulp > > > [email protected] - http://dankulp.com/blog > > > Talend Community Coder - http://coders.talend.com > -- > Daniel Kulp > [email protected] - http://dankulp.com/blog > Talend Community Coder - http://coders.talend.com > >
