hc-httpclient-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Arian <armyofda12mnk...@gmail.com>
Subject Re: Using HttpAsyncClient completely asynchronously, and shutdown client/request appropriately.
Date Tue, 05 Feb 2013 20:44:48 GMT
Hey all, I've gotten further along and had some followup questions ...

I have a single httpclient instance now for the web application...
and I am now using the PoolingClientConnectionManager so I can easily do
Multiple-Threads at same time if needed, and now using the regular
HttpClient (ditched the AsyncClient as suggested in my situation) .
I tested and I think the web app works as intended with no expected
failures (have not done a load-test though).
I was able to set a breakpoint in run() and see two threads do their work
at same time.

1. I was just curious if I need to consume the entity in my Thread's run()
and/or call releaseConnection () to do any 'cleanup' like how i do at the
end of my PostThread class below  ...
Note: I want the client available since every minute a new request to send
could come in. Not sure if this affects if i want to 'releaseConnection()'.

2. I might have 1 new request/thread being created every minute (possibly
around same time too)... The connection to 3rd party might be slow (3second
response max... but dont want user to experience it) hence why just kicking
it off to a new thread as suggested.
What would be optimal values for cm.setMaxTotal(?);
cm.setDefaultMaxPerRoute(?);? be with above parameters, and possibly lets
say coincidence 5 people spawn a new thread at same time? Not sure if this
is also useful, but the url will stay the same... only the params passed to
the HttpPost via the UrlEncodedFormEntity will change.
Would MaxTotal be 5 since maybe I want 10 threads available to do requests
at any given moment?
I didn't see documentation on what those really set (but found some code
online which says to modify it or will only have 2 threads available in the
pool or something like that):
http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingClientConnectionManager.html#setMaxTotal%28int%29


Attached is some functional code so far:

########################################################################################################################################################################
###AsyncClientConnectionManager.java


import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.params.CoreConnectionPNames;

public class AsyncClientConnectionManager
{
  private static HttpClient httpclient = null;

  public static HttpClient getInstance () throws Exception {


      if (httpclient==null) {
          try {
              PoolingClientConnectionManager cm = new
PoolingClientConnectionManager();
              cm.setMaxTotal(100);
              cm.setDefaultMaxPerRoute(25);

              httpclient = new DefaultHttpClient(cm);

              System.out.print ("Start http client");

              httpclient.getParams()
              .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 3000)
              .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
3000)
              .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 *
1024)
              .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);

              //httpclient.start();
              //?????start http client, not needed if using Connection Pool?

          } catch (Exception e){
              System.out.print ("Theres an Exception. Shutting down http
client");
              if(httpclient != null) {
                  shutdown ();
              }
              //throw e;
          }
      }

      return httpclient;

  }

  //only called when web server shuts down via ContextListener...
httpclient is aleady ready setup to always send a request (could happen
every minute)
  public static void shutdown () throws Exception {
      if(httpclient != null) {
          System.out.println("Shutting down http client");

          //httpclient.shutdown ();
          //not needed?????????? if doing below I think

          httpclient.getConnectionManager().shutdown();
      }
  }

}

########################################################################################################################################################################
###MyWebController.java

class MyWebController { //just keeping this generic for now, might use
Spring etc

  //This method is called when user posts to this form... I want to send a
request to a 3rd party
  public void formPost (HttpSession session, HttpServletResponse response,
HttpServletRequest request) {

     List<NameValuePair> params = new ArrayList<NameValuePair>();
     params.add(new BasicNameValuePair("test_param_1", "Foo"));
     params.add(new BasicNameValuePair("test_param_2", "Bar"));
     //...

     UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, "UTF-8");
     HttpPost request = new HttpPost("https://some3rdParty.com/addInfo");
     request.setEntity(ent);

     String id = UniqueIDforThisRequest;

     PostThread request_thread = new
PostThread(AsyncClientConnectionManager.getInstance(), request, id);
     request_thread.start (); //shoot off new thread as to not lock up the
web application (some3rdParty.com might be slow to respond)

     //...
     //...Do Other things while that thread goes off ... DB updates ...
returning other new View etc
     //...
  }


}
########################################################################################################################################################################
###PostThread.java

import java.io.InputStream;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;



class PostThread extends Thread {

    private final HttpClient httpClient;
    private final HttpContext context;
    private final HttpPost httppost;
    private final long id;

    public PostThread(HttpClient httpClient, HttpPost httpget, long id) {
        this.httpClient = httpClient;
        this.context = new BasicHttpContext();
        this.httppost = httpget;
        this.id = id;
    }

    /**
     * Executes the GetMethod and prints some status information.
     */
    @Override
    public void run() {

        System.out.println(id + " - about to get something from " +
httppost.getURI());

        try {
            // execute the method
            ResponseHandler<String> responseHandler = new
BasicResponseHandler();
            HttpResponse response = httpClient.execute(httppost, context);
            StatusLine sl = response.getStatusLine ();

            HttpEntity responseEntity = response.getEntity();
            String s_response = "";
            if(responseEntity!=null) {
                s_response = EntityUtils.toString(responseEntity);
            }

            if (status==200) {
                Pattern error_pattern = Pattern.compile
("regex.*look.*for.*(something).*im.*expecting.*in.*third-party's.*html.*response");
                Matcher matches = error_pattern.matcher (s_response);
                if( matches.find() ){
                    String error_value = matches.group (1);
                    if(error_value!=null && error_value.equals ("success"))
{
                        System.out.println(id + "200_PASSED_REGEX");
                    } else {
                        System.out.println(id + "200_FAILED_REGEX");
                    }
                } else {
                    System.out.println(id + "- 200 - not the expected html
in the response");
                }
            } else {
                //?????error dunno if this is cancelled/failed like
FutureCallback had options for
                System.out.println(id + "- dunno");
            }


            EntityUtils.consume(responseEntity);
            //?????not sure if needed?

            httppost.releaseConnection ();
            //?????not sure if needed?

        } catch (Exception e) {
            httppost.abort();
            System.out.println(id + " - error: " + e);

            //'real-time' send failed, Maybe send an email to us if failed
so we can send the info manually to 3rd party

        }
    }

}

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message