views:

825

answers:

1

Hi,

I'm working with a slow webservice (about 4 minutes each request) and I need to do about 100 requests in two hours, so I've decided to use multiple threads. The problem is that I can only have 2 threads, as the stub rejects all the other ones. Here I've found an explanation and possible solution:

I had the same problem. It seems that the source of it is defaultMaxConnectionsPerHost value in MultiThreadedHttpConnectionManager equals 2. Workaround for me was to create own instance of MultiThreadedHttpConnectionManager and use it in service stub, something like in example below

I've done as the author said, and passed a HttpClient to the stub with higher setMaxTotalConnections and setDefaultMaxConnectionsPerHost values, but the problem is that now the application freezes (well, it does not really freezes, but It does nothing).

Thats my code:

 public ReportsStub createReportsStub(String url, HttpTransportProperties.Authenticator auth){
  ReportsStub stub = null;
  HttpClient httpClient = null;
  try {
   stub = new ReportsStub(url);
   httpClient = createHttpClient(10,5);
   stub._getServiceClient().getOptions().setTimeOutInMilliSeconds(10000000);
   stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.AUTHENTICATE, auth);
   stub._getServiceClient().getOptions().setProperty(org.apache.axis2.transport.http.HTTPConstants.CHUNKED, false);
   stub._getServiceClient().getServiceContext().getConfigurationContext().setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient);
   return stub;
  } catch (AxisFault e) {
   e.printStackTrace();
  }
  return stub;
 }

 protected HttpClient createHttpClient(int maxTotal, int maxPerHost) {
  MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
  HttpConnectionManagerParams params = httpConnectionManager.getParams();
  if (params == null) {
        params = new HttpConnectionManagerParams();
        httpConnectionManager.setParams(params);
  }
  params.setMaxTotalConnections(maxTotal);
  params.setDefaultMaxConnectionsPerHost(maxPerHost);
  HttpClient httpClient = new HttpClient(httpConnectionManager);
  return httpClient;
}

Then I pass that stub and the request to each one of threads and run them. If I don't set the HttpClient and use the default, only two threads execute, and if I set it, the application does not work. Any idea?

A: 

I noticed this in a corporate web application that called a back-end service that could take a long period to respond. The web application would lock up because a limit of 2 connections to a single host would take hold.

You call httpConnectionManager.setParams( params ) before you call params.setDefaultMaxConnectionsPerHost(). Have you tried calling these functions in the opposite order to confirm that application of params doesn't take place within the httpConnectionManager.setParams function itself?

PP
I'm not sure that's the answer, but I'll give it a try tomorrow anyway. At this moment the corporate webservice is down, very professional.
Sergi
Hmm I think you might be right; after all you call `getParams` on the connection manager object and then you go about modifying that object. As an assertion could you check that the object you set with `setParams()` is the same as the object you're returned by the `getParams()` function?
PP
You were right @PP. It was the order in which the functions were called. At least it seems that, because now is working, but I really don't discard problems with the webservice (its reliability is horrible).
Sergi