cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Seumas Soltysik <seumas.solty...@gmail.com>
Subject Re: Minimizing thread usage for asynchronous invocations
Date Fri, 11 May 2012 06:02:54 GMT
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 <dkulp@apache.org> 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
> dkulp@apache.org - http://dankulp.com/blog
> Talend Community Coder - http://coders.talend.com
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message