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.

Reply via email to