Threading issue in AbstractHTTPSender
-------------------------------------

                 Key: AXIS2-3945
                 URL: https://issues.apache.org/jira/browse/AXIS2-3945
             Project: Axis 2.0 (Axis2)
          Issue Type: Bug
          Components: transports
    Affects Versions: 1.4
         Environment: Axis2/1.4 Java
            Reporter: Manny Lim
            Priority: Minor


The AbstractHTTPSender method getHttpClient() called by HTTPSender is not 
thread safe.  If an Operation Client performs many non-blocking send/receives, 
there will be many threads calling this method (the OutInAxisOperationClient 
creates a NonBlockingInvocationWorker for each one).

Please consider the following situation:
If the options are set as such -
REUSE_HTTP_CLIENT is set to true.
CACHED_HTTP_CLIENT is null (no HttpClient is cached).

Users may expect the OperationClient to use only one HttpClient.  However, this 
is not the case as it is possible that many threads will check the 
CACHED_HTTP_CLIENT property while it is still null.  As a result, each of those 
threads will create their own HttpClient using their own 
MultiThreadedHttpConnectionManager, and cache that (overriding any HttpClients 
that were cached before it).  Thus, many HttpClients are used, each with their 
own MultiThreadedHttpConnectionManager which comes with its own connection 
pool. A quick netstat will show that many connections are created for the 
non-blocking send/receives.

I noticed this when performing many non-blocking send/receives ( 
outInOpClient.execute(false); ) very quickly in succession, with the options 
specified above.  Subsequent non-blocking send/receives perform as expected 
since the HttpClient has been initialized and cached.

The method copied here for your reference:

    protected HttpClient getHttpClient(MessageContext msgContext) {
        HttpClient httpClient;
        Object reuse = 
msgContext.getOptions().getProperty(HTTPConstants.REUSE_HTTP_CLIENT);
        if (reuse == null) {
            reuse = 
msgContext.getConfigurationContext().getProperty(HTTPConstants.REUSE_HTTP_CLIENT);
        }
        if (reuse != null && JavaUtils.isTrueExplicitly(reuse)) {
            httpClient = (HttpClient) 
msgContext.getOptions().getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
            if (httpClient == null) {
                httpClient = (HttpClient) msgContext.getConfigurationContext()
                        .getProperty(HTTPConstants.CACHED_HTTP_CLIENT);
            }
            if (httpClient != null)
                return httpClient;
            MultiThreadedHttpConnectionManager connectionManager =
                new MultiThreadedHttpConnectionManager();
            httpClient = new HttpClient(connectionManager);
            msgContext.getConfigurationContext()
                .setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
        } else {
            HttpConnectionManager connManager =
                    (HttpConnectionManager) msgContext.getProperty(
                            HTTPConstants.MULTITHREAD_HTTP_CONNECTION_MANAGER);
            if (connManager == null) {
                connManager =
                        (HttpConnectionManager) msgContext.getProperty(
                                
HTTPConstants.MUTTITHREAD_HTTP_CONNECTION_MANAGER);
            }
            if(connManager != null){
                httpClient = new HttpClient(connManager);
            } else {
                //Multi threaded http connection manager has set as the default 
                connManager = new MultiThreadedHttpConnectionManager();
                httpClient = new HttpClient(connManager);
            }
        }

        // Get the timeout values set in the runtime
        initializeTimeouts(msgContext, httpClient);
        return httpClient;
    }

On a side note, why doesn't it check if a cached 
MultiThreadedHttpConnectionManager exists before creating an HttpClient to 
cache? It just uses its own. This would allow users more control over the 
connections and such.

Thanks,
Manny Lim

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to