I am running a 2.1.x version of CXF which uses Jetty 6.1.19. I have a testcase 
setup which has a secure endpoint(HTTPS) and an insecure endpoint(HTTP). The 
endpoints are configured to use a limited Jetty thread pool(10). I am using 
SOAPUI to drive client invocations on 25 separate threads. When I ran these two 
different scenarios, I noticed that the secure endpoint would not allow a full 
run of the SOAPUI testcase while I observed no such problem with the testcase 
using the non-secure endpoint.

While digging into the server code, I noticed that the non-secure invocations 
are being handled by the run() method of SelectChannelConnector while the 
secure invocations were being handled by the run() method of the 
SslSocketConnector. Here are the stacktraces for the two scenarios:

HTTP
        HttpConnection.handle() line: 380       
        SelectChannelConnector$ConnectorEndPoint(SelectChannelEndPoint).run() 
line: 395 
        BoundedThreadPool$PoolThread.run() line: 450    

HTTPS
Thread [btpool0-6] (Suspended (breakpoint at line 216 in 
SocketConnector$Connection))   
        SslSocketConnector$SslConnection(SocketConnector$Connection).run() 
line: 216    
        SslSocketConnector$SslConnection.run() line: 620        
        BoundedThreadPool$PoolThread.run() line: 450    

What I further noticed is that in the HTTP scenario, the 
SelectChannelConnector$ConnectorEndPoint(SelectChannelEndPoint).run() method 
looks like this:
   public void run()
    {
        try
        {
            _connection.handle();
        }
        catch (ClosedChannelException e)

while for the HTTPS scenario the 
SslSocketConnector$SslConnection(SocketConnector$Connection).run() method looks 
like this:

        public void run()
        {
            try
            {
               
                while (isStarted() && !isClosed())
                {
                    if (_connection.isIdle())
                    {
                        if (getServer().getThreadPool().isLowOnThreads())
                        {
                            int lrmit = getLowResourceMaxIdleTime();
                            if (lrmit>=0 && _sotimeout!= lrmit)
                            {
                                _sotimeout=lrmit;
                                _socket.setSoTimeout(_sotimeout);
                            }
                        }
                    }                    
                    _connection.handle();
                }
            }


The net affect is that in the HTTP scenario, each job is returned to the job 
queue after a single message is processed. In the HTTPS scenario, as long as 
the client keeps the connection open, the server will continue to process the 
current job and will continue to process messages from the associated 
connection without returning the job to the job queue. The job is only returned 
to the queue when the client closes the connection.

This leads to very different behavior for how client invocations are handled. 
In the HTTP scenario, the server essentially treats all client threads equally 
by processing a single message from a connection associated with a job and then 
putting the job back on the queue. In the HTTPS scenario, a limited set of 
clients can tie up the server for an extended period of time, by continuing to 
process the job associated with a single client. The effect is that in the 
SOAPUI testcase for the HTTPS endpoint, 10 client threads execute all the 
invocations and the other 15 threads are shutout. As long as the connection 
stays alive the job is processed. The workaround is to set a maxIdleTime 
configuration variable on the SslSocketConnector which causes the run loop of a 
job to exit after a certain period if the connection is not being used.(The 
default value for this is a rather large value.)

My basic question is why are there two different strategies for how 
jobs/connections/messages are handled by CXF/Jetty depending on whether an 
endpoint uses HTTP or HTTPS?

Regards,
Seumas

Reply via email to