Custom Executor for Service object is ignored by the CXF JAX-WS run-time when Disaptch.invokeAsync is used ----------------------------------------------------------------------------------------------------------
Key: CXF-2792 URL: https://issues.apache.org/jira/browse/CXF-2792 Project: CXF Issue Type: Bug Components: JAX-WS Runtime Affects Versions: 2.2.7 Environment: Standalone CXF-client used on Windows Vista Reporter: Leo Romanoff Hi, I'm trying to invoke 10000 external services using invokeAsync from my standalone JAX-WS client. I set my custom Executor on the Service objects. This executor is a ThreadPool with 3 threads. But it looks like it is ignored completely by the CXF run-time. Instead of an Executor, an instance of AutomaticWorkQueueImpl is used. BTW, by default, AutomaticWorkQueueImpl is an unbounded queue, so that a few thousands threads are created for processing asynchronous responses. This is of cause problematic and has a big performance impact. By providing the configuration for AutomaticWorkQueueImpl in cxf.xml, the AutomaticWorkQueueImpl can be configured to have a required number of threads and required maximum capacity. So, I did some debugging to see, why and where AutomaticWorkQueueImpl is called at all during asynchronous WS invocations using Dispatch.invokeAsync(). This is the stack trace I got: Thread [main] (Suspended (entry into method execute in AutomaticWorkQueueImpl)) AutomaticWorkQueueImpl.execute(Runnable) line: 247 HTTPConduit$WrappedOutputStream.handleResponse() line: 2153 HTTPConduit$WrappedOutputStream.close() line: 1988 HTTPConduit(AbstractConduit).close(Message) line: 66 HTTPConduit.close(Message) line: 639 MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(Message) line: 62 PhaseInterceptorChain.doIntercept(Message) line: 243 ClientImpl.invoke(ClientCallback, BindingOperationInfo, Object...) line: 422 ClientImpl.invokeWrapped(ClientCallback, QName, Object...) line: 371 DispatchImpl<T>.invokeAsync(T, AsyncHandler<T>) line: 288 TestAsyncProviderClient.invokeMyDispatch(Dispatch<Source>, Object, AsyncHandler<Source>) line: 298 TestAsyncProviderClient.testManyAsyncResponses() line: 218 TestAsyncProviderClient.main(String[]) line: 159 According to this trace, WS-response processing at the HTTP level is put for the execution on a dedicated working queue in the HTTPConduit.handleResponse method: protected void handleResponse() throws IOException { // Process retransmits until we fall out. handleRetransmits(); if (outMessage == null || outMessage.getExchange() == null || outMessage.getExchange().isSynchronous()) { handleResponseInternal(); } else { Runnable runnable = new Runnable() { public void run() { try { handleResponseInternal(); } catch (Exception e) { Message inMessage = new MessageImpl(); inMessage.setExchange(outMessage.getExchange()); inMessage.setContent(Exception.class, e); incomingObserver.onMessage(inMessage); } } }; 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); } } It is easy to see that Executor set for the JAX-WS Service is not propagated down to the HTTP transoport level, which required dedicated configuration for AutomaticWorkQueue, be it http-conduit queue or automatic work queue. For WS-responses at the user-level, i.e. by means of the JAX-WS AsyncHandler handlers, the proper Executor is taken from the Service object. -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.