hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1152381 - in /httpcomponents/httpcore/trunk: httpcore-nio/src/examples/org/apache/http/examples/nio/ httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/ httpcore-nio/src/main/java/org/apache/http/nio/pool/ httpcore/src/examples/org/a...
Date Fri, 29 Jul 2011 21:48:10 GMT
Author: olegk
Date: Fri Jul 29 21:48:08 2011
New Revision: 1152381

URL: http://svn.apache.org/viewvc?rev=1152381&view=rev
Log:
Added basic implementations of blocking and non-blocking connection pools; updated examples

Added:
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java   (with props)
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java   (with props)
    httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java   (with props)
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java   (with props)
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java   (with props)
Removed:
    httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClientConnManagement.java
Modified:
    httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java
    httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java
    httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java
    httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java
    httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpClient.java Fri Jul 29 21:48:08 2011
@@ -28,33 +28,30 @@ package org.apache.http.examples.nio;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
+import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.http.impl.nio.DefaultClientIOEventDispatch;
+import org.apache.http.impl.nio.pool.BasicNIOConnPool;
+import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
 import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.protocol.BufferingHttpClientHandler;
-import org.apache.http.nio.protocol.EventListener;
 import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.SessionRequest;
-import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
 import org.apache.http.params.SyncBasicHttpParams;
 import org.apache.http.protocol.HttpContext;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.ImmutableHttpProcessor;
 import org.apache.http.protocol.RequestConnControl;
@@ -62,15 +59,12 @@ import org.apache.http.protocol.RequestC
 import org.apache.http.protocol.RequestExpectContinue;
 import org.apache.http.protocol.RequestTargetHost;
 import org.apache.http.protocol.RequestUserAgent;
-import org.apache.http.util.EntityUtils;
 
 /**
  * Elemental example for executing HTTP requests using the non-blocking I/O model.
  * <p>
  * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client. 
- *
- * 
+ * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class NHttpClient {
 
@@ -82,33 +76,32 @@ public class NHttpClient {
             .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
             .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
             .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.USER_AGENT, "HttpComponents/1.1");
+            .setParameter(CoreProtocolPNames.USER_AGENT, "Test/1.1");
 
         final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, params);
 
+        BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, params);
+        // Limit total number of connections to just two
+        pool.setDefaultMaxPerHost(2);
+        pool.setTotalMax(2);
+
         HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 new RequestContent(),
                 new RequestTargetHost(),
                 new RequestConnControl(),
                 new RequestUserAgent(),
                 new RequestExpectContinue()});
-        
-        // We are going to use this object to synchronize between the 
-        // I/O event and main threads
-        CountDownLatch requestCount = new CountDownLatch(3);
-        
+
         BufferingHttpClientHandler handler = new BufferingHttpClientHandler(
                 httpproc,
-                new MyHttpRequestExecutionHandler(requestCount),
+                new MyHttpRequestExecutionHandler(),
                 new DefaultConnectionReuseStrategy(),
                 params);
 
-        handler.setEventListener(new EventLogger());
-        
         final IOEventDispatch ioEventDispatch = new DefaultClientIOEventDispatch(handler, params);
-        
+
         Thread t = new Thread(new Runnable() {
-         
+
             public void run() {
                 try {
                     ioReactor.execute(ioEventDispatch);
@@ -119,155 +112,118 @@ public class NHttpClient {
                 }
                 System.out.println("Shutdown");
             }
-            
+
         });
         t.start();
 
-        SessionRequest[] reqs = new SessionRequest[3];
-        reqs[0] = ioReactor.connect(
-                new InetSocketAddress("www.yahoo.com", 80), 
-                null, 
-                new HttpHost("www.yahoo.com"),
-                new MySessionRequestCallback(requestCount));
-        reqs[1] = ioReactor.connect(
-                new InetSocketAddress("www.google.com", 80), 
-                null,
-                new HttpHost("www.google.ch"),
-                new MySessionRequestCallback(requestCount));
-        reqs[2] = ioReactor.connect(
-                new InetSocketAddress("www.apache.org", 80), 
-                null,
-                new HttpHost("www.apache.org"),
-                new MySessionRequestCallback(requestCount));
-     
+        CountDownLatch requestCount = new CountDownLatch(3);
+
+        pool.lease(new HttpHost("www.google.com", 80), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+        pool.lease(new HttpHost("www.yahoo.com", 80), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+        pool.lease(new HttpHost("www.apache.org", 80), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+
         // Block until all connections signal
         // completion of the request execution
-        requestCount.await();
-        
+        requestCount.await(30, TimeUnit.SECONDS);
+
         System.out.println("Shutting down I/O reactor");
-        
+
         ioReactor.shutdown();
-        
+
         System.out.println("Done");
     }
-    
-    static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
 
-        private final static String REQUEST_SENT       = "request-sent";
-        private final static String RESPONSE_RECEIVED  = "response-received";
-        
+    static class AsyncRequestExecutor implements FutureCallback<BasicNIOPoolEntry> {
+
+        private final HttpRequest request;
+        private final BasicNIOConnPool pool;
         private final CountDownLatch requestCount;
-        
-        public MyHttpRequestExecutionHandler(final CountDownLatch requestCount) {
+        private volatile BasicNIOPoolEntry poolEntry;
+        private volatile boolean completed;
+
+        AsyncRequestExecutor(
+                final HttpRequest request,
+                final BasicNIOConnPool pool,
+                final CountDownLatch requestCount) {
             super();
+            this.request = request;
+            this.pool = pool;
             this.requestCount = requestCount;
         }
-        
-        public void initalizeContext(final HttpContext context, final Object attachment) {
-            HttpHost targetHost = (HttpHost) attachment;
-            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, targetHost);
-        }
-        
-        public void finalizeContext(final HttpContext context) {
-            Object flag = context.getAttribute(RESPONSE_RECEIVED);
-            if (flag == null) {
-                // Signal completion of the request execution
-                requestCount.countDown();
-            }
-        }
 
-        public HttpRequest submitRequest(final HttpContext context) {
-            HttpHost targetHost = (HttpHost) context.getAttribute(
-                    ExecutionContext.HTTP_TARGET_HOST);
-            Object flag = context.getAttribute(REQUEST_SENT);
-            if (flag == null) {
-                // Stick some object into the context
-                context.setAttribute(REQUEST_SENT, Boolean.TRUE);
-
-                System.out.println("--------------");
-                System.out.println("Sending request to " + targetHost);
-                System.out.println("--------------");
-                
-                return new BasicHttpRequest("GET", "/");
-            } else {
-                // No new request to submit
-                return null;
-            }
+        public void failed(final Exception ex) {
+            this.requestCount.countDown();
+            System.out.println("Connection request failed: " + ex.getMessage());
         }
-        
-        public void handleResponse(final HttpResponse response, final HttpContext context) {
-            HttpEntity entity = response.getEntity();
-            try {
-                String content = EntityUtils.toString(entity);
-                
-                System.out.println("--------------");
-                System.out.println(response.getStatusLine());
-                System.out.println("--------------");
-                System.out.println("Document length: " + content.length());
-                System.out.println("--------------");
-            } catch (IOException ex) {
-                System.err.println("I/O error: " + ex.getMessage());
-            }
 
-            context.setAttribute(RESPONSE_RECEIVED, Boolean.TRUE);
-            
-            // Signal completion of the request execution
-            requestCount.countDown();
+        public void cancelled() {
+            this.requestCount.countDown();
+            System.out.println("Connection cancelled failed");
         }
-        
-    }
-    
-    static class MySessionRequestCallback implements SessionRequestCallback {
 
-        private final CountDownLatch requestCount;        
-        
-        public MySessionRequestCallback(final CountDownLatch requestCount) {
-            super();
-            this.requestCount = requestCount;
-        }
-        
-        public void cancelled(final SessionRequest request) {
-            System.out.println("Connect request cancelled: " + request.getRemoteAddress());
-            this.requestCount.countDown();
+        public void completed(final BasicNIOPoolEntry entry) {
+            this.poolEntry = entry;
+            NHttpConnection conn = entry.getConnection();
+            conn.getContext().setAttribute("executor", this);
+            conn.requestOutput();
+            System.out.println(this.poolEntry.getRoute() + ": obtained connection from the pool");
         }
 
-        public void completed(final SessionRequest request) {
+        public HttpRequest getRequest() {
+            System.out.println(this.poolEntry.getRoute() + ": sending request " + this.request.getRequestLine());
+            return this.request;
         }
 
-        public void failed(final SessionRequest request) {
-            System.out.println("Connect request failed: " + request.getRemoteAddress());
+        public void handleResponse(final HttpResponse response) {
+            if (this.completed) {
+                return;
+            }
+            System.out.println(this.poolEntry.getRoute() + ": received response " + response.getStatusLine());
+            this.completed = true;
             this.requestCount.countDown();
+            this.pool.release(this.poolEntry, false);
         }
 
-        public void timeout(final SessionRequest request) {
-            System.out.println("Connect request timed out: " + request.getRemoteAddress());
+        public void shutdown() {
+            if (this.completed) {
+                return;
+            }
+            this.completed = true;
             this.requestCount.countDown();
+            this.pool.release(this.poolEntry, false);
         }
-        
-    }
-    
-    static class EventLogger implements EventListener {
 
-        public void connectionOpen(final NHttpConnection conn) {
-            System.out.println("Connection open: " + conn);
+    };
+
+    static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
+
+        public MyHttpRequestExecutionHandler() {
+            super();
         }
 
-        public void connectionTimeout(final NHttpConnection conn) {
-            System.out.println("Connection timed out: " + conn);
+        public void initalizeContext(final HttpContext context, final Object attachment) {
         }
 
-        public void connectionClosed(final NHttpConnection conn) {
-            System.out.println("Connection closed: " + conn);
+        public void finalizeContext(final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            if (executor != null) {
+                executor.shutdown();
+            }
         }
 
-        public void fatalIOException(final IOException ex, final NHttpConnection conn) {
-            System.err.println("I/O error: " + ex.getMessage());
+        public HttpRequest submitRequest(final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            return executor.getRequest();
         }
 
-        public void fatalProtocolException(final HttpException ex, final NHttpConnection conn) {
-            System.err.println("HTTP error: " + ex.getMessage());
+        public void handleResponse(final HttpResponse response, final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            executor.handleResponse(response);
         }
-        
+
     }
 
 }

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java Fri Jul 29 21:48:08 2011
@@ -28,34 +28,31 @@ package org.apache.http.examples.nio;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import javax.net.ssl.SSLContext;
 
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpException;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.HttpResponse;
+import org.apache.http.concurrent.FutureCallback;
 import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.nio.pool.BasicNIOConnPool;
+import org.apache.http.impl.nio.pool.BasicNIOPoolEntry;
 import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
 import org.apache.http.impl.nio.ssl.SSLClientIOEventDispatch;
 import org.apache.http.message.BasicHttpRequest;
 import org.apache.http.nio.NHttpConnection;
 import org.apache.http.nio.protocol.BufferingHttpClientHandler;
-import org.apache.http.nio.protocol.EventListener;
 import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
 import org.apache.http.nio.reactor.ConnectingIOReactor;
 import org.apache.http.nio.reactor.IOEventDispatch;
-import org.apache.http.nio.reactor.SessionRequest;
-import org.apache.http.nio.reactor.SessionRequestCallback;
 import org.apache.http.params.CoreConnectionPNames;
-import org.apache.http.params.HttpParams;
 import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
 import org.apache.http.params.SyncBasicHttpParams;
-import org.apache.http.protocol.ExecutionContext;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.protocol.HttpProcessor;
 import org.apache.http.protocol.ImmutableHttpProcessor;
@@ -64,15 +61,12 @@ import org.apache.http.protocol.RequestC
 import org.apache.http.protocol.RequestExpectContinue;
 import org.apache.http.protocol.RequestTargetHost;
 import org.apache.http.protocol.RequestUserAgent;
-import org.apache.http.util.EntityUtils;
 
 /**
  * Elemental example for executing HTTPS requests using the non-blocking I/O model.
  * <p>
  * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client. 
- *
- * 
+ * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class NHttpSSLClient {
 
@@ -84,40 +78,39 @@ public class NHttpSSLClient {
             .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
             .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
             .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
-            .setParameter(CoreProtocolPNames.USER_AGENT, "Jakarta-HttpComponents-NIO/1.1");
+            .setParameter(CoreProtocolPNames.USER_AGENT, "Test/1.1");
 
         final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(2, params);
 
+        BasicNIOConnPool pool = new BasicNIOConnPool(ioReactor, params);
+        // Limit total number of connections to just two
+        pool.setDefaultMaxPerHost(2);
+        pool.setTotalMax(2);
+
         HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 new RequestContent(),
                 new RequestTargetHost(),
                 new RequestConnControl(),
                 new RequestUserAgent(),
                 new RequestExpectContinue()});
-        
+
         // Initialize default SSL context
         SSLContext sslcontext = SSLContext.getInstance("SSL");
         sslcontext.init(null, null, null);
-        
-        // We are going to use this object to synchronize between the 
-        // I/O event and main threads
-        CountDownLatch requestCount = new CountDownLatch(3);
-        
+
         BufferingHttpClientHandler handler = new BufferingHttpClientHandler(
                 httpproc,
-                new MyHttpRequestExecutionHandler(requestCount),
+                new MyHttpRequestExecutionHandler(),
                 new DefaultConnectionReuseStrategy(),
                 params);
 
-        handler.setEventListener(new EventLogger());
-        
         final IOEventDispatch ioEventDispatch = new SSLClientIOEventDispatch(
                 handler,
                 sslcontext,
                 params);
-        
+
         Thread t = new Thread(new Runnable() {
-         
+
             public void run() {
                 try {
                     ioReactor.execute(ioEventDispatch);
@@ -128,155 +121,118 @@ public class NHttpSSLClient {
                 }
                 System.out.println("Shutdown");
             }
-            
+
         });
         t.start();
 
-        SessionRequest[] reqs = new SessionRequest[3];
-        reqs[0] = ioReactor.connect(
-                new InetSocketAddress("www.netscape.com", 443), 
-                null, 
-                new HttpHost("www.netscape.com", 443),
-                new MySessionRequestCallback(requestCount));
-        reqs[1] = ioReactor.connect(
-                new InetSocketAddress("www.verisign.com", 443), 
-                null,
-                new HttpHost("www.verisign.com", 443),
-                new MySessionRequestCallback(requestCount));
-        reqs[2] = ioReactor.connect(
-                new InetSocketAddress("www.yahoo.com", 443), 
-                null,
-                new HttpHost("www.yahoo.com", 443),
-                new MySessionRequestCallback(requestCount));
-     
+        CountDownLatch requestCount = new CountDownLatch(3);
+
+        pool.lease(new HttpHost("www.verisign.com", 443), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+        pool.lease(new HttpHost("www.yahoo.com", 443), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+        pool.lease(new HttpHost("apache.org", 443), null,
+                new AsyncRequestExecutor(new BasicHttpRequest("GET", "/"), pool, requestCount));
+
         // Block until all connections signal
         // completion of the request execution
-        requestCount.await();
+        requestCount.await(30, TimeUnit.SECONDS);
 
         System.out.println("Shutting down I/O reactor");
-        
+
         ioReactor.shutdown();
-        
+
         System.out.println("Done");
     }
-    
-    static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
 
-        private final static String REQUEST_SENT       = "request-sent";
-        private final static String RESPONSE_RECEIVED  = "response-received";
-        
+    static class AsyncRequestExecutor implements FutureCallback<BasicNIOPoolEntry> {
+
+        private final HttpRequest request;
+        private final BasicNIOConnPool pool;
         private final CountDownLatch requestCount;
-        
-        public MyHttpRequestExecutionHandler(final CountDownLatch requestCount) {
+        private volatile BasicNIOPoolEntry poolEntry;
+        private volatile boolean completed;
+
+        AsyncRequestExecutor(
+                final HttpRequest request,
+                final BasicNIOConnPool pool,
+                final CountDownLatch requestCount) {
             super();
+            this.request = request;
+            this.pool = pool;
             this.requestCount = requestCount;
         }
-        
-        public void initalizeContext(final HttpContext context, final Object attachment) {
-            HttpHost targetHost = (HttpHost) attachment;
-            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, targetHost);
-        }
-
-        public void finalizeContext(final HttpContext context) {
-            Object flag = context.getAttribute(RESPONSE_RECEIVED);
-            if (flag == null) {
-                // Signal completion of the request execution
-                this.requestCount.countDown();
-            }
-        }
 
-        public HttpRequest submitRequest(final HttpContext context) {
-            HttpHost targetHost = (HttpHost) context.getAttribute(
-                    ExecutionContext.HTTP_TARGET_HOST);
-            Object token = context.getAttribute(REQUEST_SENT);
-            if (token == null) {
-                // Stick some object into the context
-                context.setAttribute(REQUEST_SENT, Boolean.TRUE);
-
-                System.out.println("--------------");
-                System.out.println("Sending request to " + targetHost);
-                System.out.println("--------------");
-                
-                return new BasicHttpRequest("GET", "/");
-            } else {
-                // No new request to submit
-                return null;
-            }
+        public void failed(final Exception ex) {
+            this.requestCount.countDown();
+            System.out.println("Connection request failed: " + ex.getMessage());
         }
-        
-        public void handleResponse(final HttpResponse response, final HttpContext context) {
-            HttpEntity entity = response.getEntity();
-            try {
-                String content = EntityUtils.toString(entity);
-                
-                System.out.println("--------------");
-                System.out.println(response.getStatusLine());
-                System.out.println("--------------");
-                System.out.println("Document length: " + content.length());
-                System.out.println("--------------");
-            } catch (IOException ex) {
-                System.err.println("I/O error: " + ex.getMessage());
-            }
 
-            context.setAttribute(RESPONSE_RECEIVED, Boolean.TRUE);
-            
-            // Signal completion of the request execution
+        public void cancelled() {
             this.requestCount.countDown();
+            System.out.println("Connection cancelled failed");
         }
-        
-    }
-    
-    static class MySessionRequestCallback implements SessionRequestCallback {
 
-        private final CountDownLatch requestCount;        
-        
-        public MySessionRequestCallback(final CountDownLatch requestCount) {
-            super();
-            this.requestCount = requestCount;
-        }
-        
-        public void cancelled(final SessionRequest request) {
-            System.out.println("Connect request cancelled: " + request.getRemoteAddress());
-            this.requestCount.countDown();
+        public void completed(final BasicNIOPoolEntry entry) {
+            this.poolEntry = entry;
+            NHttpConnection conn = entry.getConnection();
+            conn.getContext().setAttribute("executor", this);
+            conn.requestOutput();
+            System.out.println(this.poolEntry.getRoute() + ": obtained connection from the pool");
         }
 
-        public void completed(final SessionRequest request) {
+        public HttpRequest getRequest() {
+            System.out.println(this.poolEntry.getRoute() + ": sending request " + this.request.getRequestLine());
+            return this.request;
         }
 
-        public void failed(final SessionRequest request) {
-            System.out.println("Connect request failed: " + request.getRemoteAddress());
+        public void handleResponse(final HttpResponse response) {
+            if (this.completed) {
+                return;
+            }
+            System.out.println(this.poolEntry.getRoute() + ": received response " + response.getStatusLine());
+            this.completed = true;
             this.requestCount.countDown();
+            this.pool.release(this.poolEntry, false);
         }
 
-        public void timeout(final SessionRequest request) {
-            System.out.println("Connect request timed out: " + request.getRemoteAddress());
+        public void shutdown() {
+            if (this.completed) {
+                return;
+            }
+            this.completed = true;
             this.requestCount.countDown();
+            this.pool.release(this.poolEntry, false);
         }
-        
-    }
-    
-    static class EventLogger implements EventListener {
 
-        public void connectionOpen(final NHttpConnection conn) {
-            System.out.println("Connection open: " + conn);
+    };
+
+    static class MyHttpRequestExecutionHandler implements HttpRequestExecutionHandler {
+
+        public MyHttpRequestExecutionHandler() {
+            super();
         }
 
-        public void connectionTimeout(final NHttpConnection conn) {
-            System.out.println("Connection timed out: " + conn);
+        public void initalizeContext(final HttpContext context, final Object attachment) {
         }
 
-        public void connectionClosed(final NHttpConnection conn) {
-            System.out.println("Connection closed: " + conn);
+        public void finalizeContext(final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            if (executor != null) {
+                executor.shutdown();
+            }
         }
 
-        public void fatalIOException(final IOException ex, final NHttpConnection conn) {
-            System.err.println("I/O error: " + ex.getMessage());
+        public HttpRequest submitRequest(final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            return executor.getRequest();
         }
 
-        public void fatalProtocolException(final HttpException ex, final NHttpConnection conn) {
-            System.err.println("HTTP error: " + ex.getMessage());
+        public void handleResponse(final HttpResponse response, final HttpContext context) {
+            AsyncRequestExecutor executor = (AsyncRequestExecutor) context.getAttribute("executor");
+            executor.handleResponse(response);
         }
-        
+
     }
 
 }

Added: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java?rev=1152381&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java Fri Jul 29 21:48:08 2011
@@ -0,0 +1,92 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.nio.pool;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpResponseFactory;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.nio.DefaultNHttpClientConnection;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.nio.pool.AbstractNIOConnPool;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.util.ByteBufferAllocator;
+import org.apache.http.nio.util.HeapByteBufferAllocator;
+import org.apache.http.params.HttpParams;
+
+public class BasicNIOConnPool extends AbstractNIOConnPool<HttpHost, NHttpClientConnection, BasicNIOPoolEntry> {
+
+    private final HttpResponseFactory responseFactory;
+    private final ByteBufferAllocator allocator;
+    private final HttpParams params;
+
+    public BasicNIOConnPool(final ConnectingIOReactor ioreactor, final HttpParams params) {
+        super(ioreactor, 2, 20);
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP params may not be null");
+        }
+        this.responseFactory = new DefaultHttpResponseFactory();
+        this.allocator = new HeapByteBufferAllocator();
+        this.params = params;
+    }
+
+    @Override
+    protected SocketAddress resolveRemoteAddress(final HttpHost host) {
+        return new InetSocketAddress(host.getHostName(), host.getPort());
+    }
+
+    @Override
+    protected SocketAddress resolveLocalAddress(final HttpHost host) {
+        return null;
+    }
+
+    @Override
+    protected NHttpClientConnection createConnection(final HttpHost route, final IOSession session) {
+        return new DefaultNHttpClientConnection(session,
+                this.responseFactory, this.allocator, this.params);
+    }
+
+    @Override
+    protected BasicNIOPoolEntry createEntry(final HttpHost host, final NHttpClientConnection conn) {
+        return new BasicNIOPoolEntry(host, conn);
+    }
+
+    @Override
+    protected void closeEntry(final BasicNIOPoolEntry entry) {
+        HttpConnection conn = entry.getConnection();
+        try {
+            conn.close();
+        } catch (IOException ignore) {
+        }
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOConnPool.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java?rev=1152381&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java (added)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java Fri Jul 29 21:48:08 2011
@@ -0,0 +1,39 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.nio.pool;
+
+import org.apache.http.HttpHost;
+import org.apache.http.nio.NHttpClientConnection;
+import org.apache.http.pool.PoolEntry;
+
+public class BasicNIOPoolEntry extends PoolEntry<HttpHost, NHttpClientConnection> {
+
+    public BasicNIOPoolEntry(final HttpHost route, final NHttpClientConnection conn) {
+        super(route, conn);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/impl/nio/pool/BasicNIOPoolEntry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java (original)
+++ httpcomponents/httpcore/trunk/httpcore-nio/src/main/java/org/apache/http/nio/pool/AbstractNIOConnPool.java Fri Jul 29 21:48:08 2011
@@ -196,6 +196,9 @@ public abstract class AbstractNIOConnPoo
     }
 
     public void release(final E entry, boolean reusable) {
+        if (entry == null) {
+            return;
+        }
         if (this.isShutDown) {
             return;
         }

Modified: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpGet.java Fri Jul 29 21:48:08 2011
@@ -54,18 +54,15 @@ import org.apache.http.protocol.RequestU
 import org.apache.http.util.EntityUtils;
 
 /**
- * Elemental example for executing a GET request.
+ * Elemental example for executing multiple GET requests sequentially.
  * <p>
  * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client. 
- *
- *
- *
+ * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class ElementalHttpGet {
 
     public static void main(String[] args) throws Exception {
-        
+
         HttpParams params = new SyncBasicHttpParams();
         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, "UTF-8");
@@ -80,9 +77,9 @@ public class ElementalHttpGet {
                 new RequestConnControl(),
                 new RequestUserAgent(),
                 new RequestExpectContinue()});
-        
+
         HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
-        
+
         HttpContext context = new BasicHttpContext(null);
         HttpHost host = new HttpHost("localhost", 8080);
 
@@ -93,12 +90,12 @@ public class ElementalHttpGet {
         context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
 
         try {
-            
+
             String[] targets = {
                     "/",
-                    "/servlets-examples/servlet/RequestInfoExample", 
+                    "/servlets-examples/servlet/RequestInfoExample",
                     "/somewhere%20in%20pampa"};
-            
+
             for (int i = 0; i < targets.length; i++) {
                 if (!conn.isOpen()) {
                     Socket socket = new Socket(host.getHostName(), host.getPort());
@@ -106,13 +103,13 @@ public class ElementalHttpGet {
                 }
                 BasicHttpRequest request = new BasicHttpRequest("GET", targets[i]);
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
-                
+
                 request.setParams(params);
                 httpexecutor.preProcess(request, httpproc, context);
                 HttpResponse response = httpexecutor.execute(request, conn, context);
                 response.setParams(params);
                 httpexecutor.postProcess(response, httpproc, context);
-                
+
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");
@@ -126,5 +123,5 @@ public class ElementalHttpGet {
             conn.close();
         }
     }
-    
+
 }

Modified: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalHttpPost.java Fri Jul 29 21:48:08 2011
@@ -59,24 +59,21 @@ import org.apache.http.protocol.RequestU
 import org.apache.http.util.EntityUtils;
 
 /**
- * Elemental example for executing a POST request.
+ * Elemental example for executing multiple POST requests sequentially.
  * <p>
  * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
- * It is NOT intended to demonstrate the most efficient way of building an HTTP client. 
- *
- *
- *
+ * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
  */
 public class ElementalHttpPost {
 
     public static void main(String[] args) throws Exception {
-        
+
         HttpParams params = new SyncBasicHttpParams();
         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
         HttpProtocolParams.setContentCharset(params, "UTF-8");
-        HttpProtocolParams.setUserAgent(params, "HttpComponents/1.1");
+        HttpProtocolParams.setUserAgent(params, "Test/1.1");
         HttpProtocolParams.setUseExpectContinue(params, true);
-        
+
         HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                 // Required protocol interceptors
                 new RequestContent(),
@@ -85,13 +82,13 @@ public class ElementalHttpPost {
                 new RequestConnControl(),
                 new RequestUserAgent(),
                 new RequestExpectContinue()});
-        
+
         HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
 
         HttpContext context = new BasicHttpContext(null);
-        
+
         HttpHost host = new HttpHost("localhost", 8080);
-        
+
         DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
         ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
 
@@ -99,7 +96,7 @@ public class ElementalHttpPost {
         context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
 
         try {
-            
+
             HttpEntity[] requestBodies = {
                     new StringEntity(
                             "This is the first test request", "UTF-8"),
@@ -110,13 +107,13 @@ public class ElementalHttpPost {
                                     "This is the third test request (will be chunked)"
                                     .getBytes("UTF-8")), -1)
             };
-            
+
             for (int i = 0; i < requestBodies.length; i++) {
                 if (!conn.isOpen()) {
                     Socket socket = new Socket(host.getHostName(), host.getPort());
                     conn.bind(socket, params);
                 }
-                BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST", 
+                BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
                         "/servlets-examples/servlet/RequestInfoExample");
                 request.setEntity(requestBodies[i]);
                 System.out.println(">> Request URI: " + request.getRequestLine().getUri());
@@ -126,7 +123,7 @@ public class ElementalHttpPost {
                 HttpResponse response = httpexecutor.execute(request, conn, context);
                 response.setParams(params);
                 httpexecutor.postProcess(response, httpproc, context);
-                
+
                 System.out.println("<< Response: " + response.getStatusLine());
                 System.out.println(EntityUtils.toString(response.getEntity()));
                 System.out.println("==============");
@@ -138,7 +135,7 @@ public class ElementalHttpPost {
             }
         } finally {
             conn.close();
-        }        
+        }
     }
-    
+
 }

Added: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java?rev=1152381&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java (added)
+++ httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java Fri Jul 29 21:48:08 2011
@@ -0,0 +1,165 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.examples;
+
+import java.io.IOException;
+import java.util.concurrent.Future;
+
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpException;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequestInterceptor;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.impl.DefaultConnectionReuseStrategy;
+import org.apache.http.impl.pool.BasicConnPool;
+import org.apache.http.impl.pool.BasicPoolEntry;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.params.SyncBasicHttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.ExecutionContext;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestExecutor;
+import org.apache.http.protocol.ImmutableHttpProcessor;
+import org.apache.http.protocol.RequestConnControl;
+import org.apache.http.protocol.RequestContent;
+import org.apache.http.protocol.RequestExpectContinue;
+import org.apache.http.protocol.RequestTargetHost;
+import org.apache.http.protocol.RequestUserAgent;
+import org.apache.http.util.EntityUtils;
+
+/**
+ * Elemental example for executing multiple GET requests from different threads using a connection
+ * pool.
+ * <p>
+ * Please note the purpose of this application is demonstrate the usage of HttpCore APIs.
+ * It is NOT intended to demonstrate the most efficient way of building an HTTP client.
+ */
+public class ElementalPoolingHttpGet {
+
+    public static void main(String[] args) throws Exception {
+
+        final HttpParams params = new SyncBasicHttpParams();
+        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+        HttpProtocolParams.setContentCharset(params, "UTF-8");
+        HttpProtocolParams.setUserAgent(params, "Test/1.1");
+        HttpProtocolParams.setUseExpectContinue(params, true);
+
+        final HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
+                // Required protocol interceptors
+                new RequestContent(),
+                new RequestTargetHost(),
+                // Recommended protocol interceptors
+                new RequestConnControl(),
+                new RequestUserAgent(),
+                new RequestExpectContinue()});
+
+        final HttpRequestExecutor httpexecutor = new HttpRequestExecutor();
+
+        final BasicConnPool pool = new BasicConnPool(params);
+        pool.setDefaultMaxPerHost(2);
+        pool.setTotalMax(2);
+
+        HttpHost[] targets = {
+                new HttpHost("www.google.com", 80),
+                new HttpHost("www.yahoo.com", 80),
+                new HttpHost("www.apache.com", 80)
+        };
+
+        class WorkerThread extends Thread {
+
+            private final HttpHost target;
+
+            WorkerThread(final HttpHost target) {
+                super();
+                this.target = target;
+            }
+
+            @Override
+            public void run() {
+                try {
+                    Future<BasicPoolEntry> future = pool.lease(this.target, null);
+
+                    boolean reusable = true;
+                    BasicPoolEntry entry = future.get();
+                    try {
+                        HttpClientConnection conn = entry.getConnection();
+                        HttpContext context = new BasicHttpContext(null);
+                        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
+                        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, this.target);
+
+                        BasicHttpRequest request = new BasicHttpRequest("GET", "/");
+                        System.out.println(">> Request URI: " + request.getRequestLine().getUri());
+
+                        request.setParams(params);
+                        httpexecutor.preProcess(request, httpproc, context);
+                        HttpResponse response = httpexecutor.execute(request, conn, context);
+                        response.setParams(params);
+                        httpexecutor.postProcess(response, httpproc, context);
+
+                        System.out.println("<< Response: " + response.getStatusLine());
+                        System.out.println(EntityUtils.toString(response.getEntity()));
+
+                        ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();
+                        reusable = connStrategy.keepAlive(response, context);
+                    } catch (IOException ex) {
+                        reusable = false;
+                        throw ex;
+                    } catch (HttpException ex) {
+                        reusable = false;
+                        throw ex;
+                    } finally {
+                        if (reusable) {
+                            System.out.println("Connection kept alive...");
+                        }
+                        pool.release(entry, reusable);
+                    }
+                } catch (Exception ex) {
+                    System.out.println("Request to " + this.target + " failed: " + ex.getMessage());
+                }
+            }
+
+        };
+
+        WorkerThread[] workers = new WorkerThread[targets.length];
+        for (int i = 0; i < workers.length; i++) {
+            workers[i] = new WorkerThread(targets[i]);
+        }
+        for (int i = 0; i < workers.length; i++) {
+            workers[i].start();
+        }
+        for (int i = 0; i < workers.length; i++) {
+            workers[i].join();
+        }
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore/src/examples/org/apache/http/examples/ElementalPoolingHttpGet.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java?rev=1152381&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java (added)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java Fri Jul 29 21:48:08 2011
@@ -0,0 +1,99 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.pool;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpConnection;
+import org.apache.http.HttpHost;
+import org.apache.http.impl.DefaultHttpClientConnection;
+import org.apache.http.params.HttpConnectionParams;
+import org.apache.http.params.HttpParams;
+import org.apache.http.pool.AbstractConnPool;
+
+public class BasicConnPool extends AbstractConnPool<HttpHost, HttpClientConnection, BasicPoolEntry> {
+
+    private final SSLSocketFactory sslfactory;
+    private final HttpParams params;
+
+    public BasicConnPool(final SSLSocketFactory sslfactory, final HttpParams params) {
+        super(2, 20);
+        if (params == null) {
+            throw new IllegalArgumentException("HTTP params may not be null");
+        }
+        this.sslfactory = sslfactory;
+        this.params = params;
+    }
+
+    public BasicConnPool(final HttpParams params) {
+        this(null, params);
+    }
+
+    @Override
+    protected HttpClientConnection createConnection(final HttpHost host) throws IOException {
+        DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
+        String scheme = host.getSchemeName();
+        Socket socket = null;
+        if ("http".equalsIgnoreCase(scheme)) {
+            socket = new Socket();
+        } if ("https".equalsIgnoreCase(scheme)) {
+            if (this.sslfactory != null) {
+                socket = this.sslfactory.createSocket();
+            }
+        }
+        if (socket == null) {
+            throw new IOException(scheme + " scheme is not supported");
+        }
+        int connTimeout = HttpConnectionParams.getConnectionTimeout(params);
+        int soTimeout = HttpConnectionParams.getSoTimeout(params);
+
+        socket.setSoTimeout(soTimeout);
+        socket.connect(new InetSocketAddress(host.getHostName(), host.getPort()), connTimeout);
+        conn.bind(socket, this.params);
+        return conn;
+    }
+
+    @Override
+    protected BasicPoolEntry createEntry(final HttpHost host, final HttpClientConnection conn) {
+        return new BasicPoolEntry(host, conn);
+    }
+
+    @Override
+    protected void closeEntry(final BasicPoolEntry entry) {
+        HttpConnection conn = entry.getConnection();
+        try {
+            conn.close();
+        } catch (IOException ignore) {
+        }
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicConnPool.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java?rev=1152381&view=auto
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java (added)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java Fri Jul 29 21:48:08 2011
@@ -0,0 +1,39 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.http.impl.pool;
+
+import org.apache.http.HttpClientConnection;
+import org.apache.http.HttpHost;
+import org.apache.http.pool.PoolEntry;
+
+public class BasicPoolEntry extends PoolEntry<HttpHost, HttpClientConnection> {
+
+    public BasicPoolEntry(final HttpHost route, final HttpClientConnection conn) {
+        super(route, conn);
+    }
+
+}

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/impl/pool/BasicPoolEntry.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java?rev=1152381&r1=1152380&r2=1152381&view=diff
==============================================================================
--- httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java (original)
+++ httpcomponents/httpcore/trunk/httpcore/src/main/java/org/apache/http/pool/PoolEntry.java Fri Jul 29 21:48:08 2011
@@ -43,8 +43,7 @@ public class PoolEntry<T, C> {
     private long updated;
     private long expiry;
 
-    public PoolEntry(final T route, final C conn,
-            final long timeToLive, final TimeUnit tunit) {
+    public PoolEntry(final T route, final C conn, final long timeToLive, final TimeUnit tunit) {
         super();
         if (route == null) {
             throw new IllegalArgumentException("Route may not be null");



Mime
View raw message