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