[ 
https://issues.apache.org/jira/browse/AXIS2-3945?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Supun Kamburugamuva resolved AXIS2-3945.
----------------------------------------

    Resolution: Fixed

Fixed by synchronization of the getHttpClient method

> Threading issue in AbstractHTTPSender
> -------------------------------------
>
>                 Key: AXIS2-3945
>                 URL: https://issues.apache.org/jira/browse/AXIS2-3945
>             Project: 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