You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2009/09/12 22:30:21 UTC

svn commit: r814229 [2/2] - in /httpcomponents/asynchttpclient/trunk: ./ src/ src/examples/ src/examples/org/ src/examples/org/apache/ src/examples/org/apache/http/ src/examples/org/apache/http/examples/ src/examples/org/apache/http/examples/nio/ src/e...

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/RouteResolver.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/RouteResolver.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/RouteResolver.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/RouteResolver.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,37 @@
+/*
+ * ====================================================================
+ * 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.net.SocketAddress;
+
+public interface RouteResolver<T> {
+
+    SocketAddress resolveRemoteAddress(T route);
+
+    SocketAddress resolveLocalAddress(T route);
+
+}

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

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/RouteResolver.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

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

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPool.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPool.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPool.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,382 @@
+/*
+ * ====================================================================
+ * 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.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.http.nio.conn.PoolStats;
+import org.apache.http.nio.reactor.ConnectingIOReactor;
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionRequest;
+import org.apache.http.nio.reactor.SessionRequestCallback;
+
+public class SessionPool<T> {
+
+    private final ConnectingIOReactor ioreactor;
+    private final SessionRequestCallback sessionRequestCallback;
+    private final RouteResolver<T> routeResolver;
+    private final Map<T, SessionPoolForRoute<T>> routeToPool;
+    private final LinkedList<LeaseRequest<T>> leasingRequests;
+    private final Set<SessionRequest> pendingSessions;
+    private final Set<PoolEntry<T>> leasedSessions;
+    private final LinkedList<PoolEntry<T>> availableSessions;
+    private final Map<T, Integer> maxPerRoute;
+    private final Lock lock;
+
+    private volatile boolean isShutDown;
+    private volatile int defaultMaxPerRoute;
+    private volatile int maxTotal;
+
+    public SessionPool(
+            final ConnectingIOReactor ioreactor,
+            final RouteResolver<T> routeResolver,
+            int defaultMaxPerRoute,
+            int maxTotal) {
+        super();
+        if (ioreactor == null) {
+            throw new IllegalArgumentException("I/O reactor may not be null");
+        }
+        if (routeResolver == null) {
+            throw new IllegalArgumentException("Route resolver may not be null");
+        }
+        this.ioreactor = ioreactor;
+        this.sessionRequestCallback = new InternalSessionRequestCallback();
+        this.routeResolver = routeResolver;
+        this.routeToPool = new HashMap<T, SessionPoolForRoute<T>>();
+        this.leasingRequests = new LinkedList<LeaseRequest<T>>();
+        this.pendingSessions = new HashSet<SessionRequest>();
+        this.leasedSessions = new HashSet<PoolEntry<T>>();
+        this.availableSessions = new LinkedList<PoolEntry<T>>();
+        this.maxPerRoute = new HashMap<T, Integer>();
+        this.lock = new ReentrantLock();
+        this.defaultMaxPerRoute = defaultMaxPerRoute;
+        this.maxTotal = maxTotal;
+    }
+
+    public void shutdown() {
+        if (this.isShutDown) {
+            return ;
+        }
+        this.isShutDown = true;
+        this.lock.lock();
+        try {
+            for (SessionPoolForRoute<T> pool: this.routeToPool.values()) {
+                pool.shutdown();
+            }
+            this.routeToPool.clear();
+
+            this.leasedSessions.clear();
+            this.pendingSessions.clear();
+            this.availableSessions.clear();
+            this.leasingRequests.clear();
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    private SessionPoolForRoute<T> getPool(final T route) {
+        SessionPoolForRoute<T> pool = this.routeToPool.get(route);
+        if (pool == null) {
+            pool = new SessionPoolForRoute<T>(route);
+            this.routeToPool.put(route, pool);
+        }
+        return pool;
+    }
+
+    public void lease(final T route, final Object state, final PoolEntryCallback<T> callback) {
+        if (this.isShutDown) {
+            throw new IllegalStateException("Session pool has been shut down");
+        }
+        this.lock.lock();
+        try {
+            LeaseRequest<T> request = new LeaseRequest<T>(route, state, callback);
+            this.leasingRequests.add(request);
+
+            processPendingRequests();
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    public void release(final PoolEntry<T> entry, boolean reusable) {
+        if (this.isShutDown) {
+            return;
+        }
+        this.lock.lock();
+        try {
+            if (this.leasedSessions.remove(entry)) {
+                SessionPoolForRoute<T> pool = getPool(entry.getRoute());
+                pool.freeEntry(entry, reusable);
+                if (reusable) {
+                    this.availableSessions.add(entry);
+                }
+                processPendingRequests();
+            }
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    private int getAllocatedTotal() {
+        return this.leasedSessions.size() +
+            this.pendingSessions.size() +
+            this.availableSessions.size();
+    }
+
+    private void entryShutdown(final PoolEntry<T> entry) {
+        IOSession iosession = entry.getIOSession();
+        iosession.close();
+    }
+
+    private void processPendingRequests() {
+        ListIterator<LeaseRequest<T>> it = this.leasingRequests.listIterator();
+        while (it.hasNext()) {
+            LeaseRequest<T> request = it.next();
+
+            T route = request.getRoute();
+            Object state = request.getState();
+            PoolEntryCallback<T> callback = request.getCallback();
+
+            if (getAllocatedTotal() >= this.maxTotal) {
+                if (!this.availableSessions.isEmpty()) {
+                    PoolEntry<T> entry = this.availableSessions.remove();
+                    entryShutdown(entry);
+                    SessionPoolForRoute<T> pool = getPool(entry.getRoute());
+                    pool.freeEntry(entry, false);
+                }
+            }
+
+            SessionPoolForRoute<T> pool = getPool(request.getRoute());
+            PoolEntry<T> entry = pool.getFreeEntry(state);
+            if (entry != null) {
+                it.remove();
+                this.availableSessions.remove(entry);
+                this.leasedSessions.add(entry);
+                callback.completed(entry);
+            } else {
+                int max = getMaxPerRoute(route);
+                if (pool.getAvailableCount() > 0 && pool.getAllocatedCount() >= max) {
+                    entry = pool.deleteLastUsed();
+                    if (entry != null) {
+                        this.availableSessions.remove(entry);
+                        entryShutdown(entry);
+                    }
+                }
+                if (pool.getAllocatedCount() < max) {
+                    it.remove();
+                    SessionRequest sessionRequest = this.ioreactor.connect(
+                            this.routeResolver.resolveRemoteAddress(route),
+                            this.routeResolver.resolveLocalAddress(route),
+                            route,
+                            this.sessionRequestCallback);
+                    pool.addPending(sessionRequest, callback);
+                }
+            }
+        }
+    }
+
+    protected void requestCompleted(final SessionRequest request) {
+        if (this.isShutDown) {
+            return;
+        }
+        @SuppressWarnings("unchecked")
+        T route = (T) request.getAttachment();
+        this.lock.lock();
+        try {
+            this.pendingSessions.remove(request);
+            SessionPoolForRoute<T> pool = getPool(route);
+            PoolEntry<T> entry = pool.completed(request);
+            this.leasedSessions.add(entry);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    protected void requestCancelled(final SessionRequest request) {
+        if (this.isShutDown) {
+            return;
+        }
+        @SuppressWarnings("unchecked")
+        T route = (T) request.getAttachment();
+        this.lock.lock();
+        try {
+            this.pendingSessions.remove(request);
+            SessionPoolForRoute<T> pool = getPool(route);
+            pool.cancelled(request);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    protected void requestFailed(final SessionRequest request) {
+        if (this.isShutDown) {
+            return;
+        }
+        @SuppressWarnings("unchecked")
+        T route = (T) request.getAttachment();
+        this.lock.lock();
+        try {
+            this.pendingSessions.remove(request);
+            SessionPoolForRoute<T> pool = getPool(route);
+            pool.failed(request);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    protected void requestTimeout(final SessionRequest request) {
+        if (this.isShutDown) {
+            return;
+        }
+        @SuppressWarnings("unchecked")
+        T route = (T) request.getAttachment();
+        this.lock.lock();
+        try {
+            this.pendingSessions.remove(request);
+            SessionPoolForRoute<T> pool = getPool(route);
+            pool.timeout(request);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    private int getMaxPerRoute(final T route) {
+        Integer v = this.maxPerRoute.get(route);
+        if (v != null) {
+            return v.intValue();
+        } else {
+            return this.defaultMaxPerRoute;
+        }
+    }
+
+    public void setTotalMax(int max) {
+        if (max <= 0) {
+            throw new IllegalArgumentException("Max value may not be negative or zero");
+        }
+        this.lock.lock();
+        try {
+            this.maxTotal = max;
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    public void setDefaultMaxPerHost(int max) {
+        if (max <= 0) {
+            throw new IllegalArgumentException("Max value may not be negative or zero");
+        }
+        this.lock.lock();
+        try {
+            this.defaultMaxPerRoute = max;
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    public void setMaxPerHost(final T route, int max) {
+        if (route == null) {
+            throw new IllegalArgumentException("Route may not be null");
+        }
+        if (max <= 0) {
+            throw new IllegalArgumentException("Max value may not be negative or zero");
+        }
+        this.lock.lock();
+        try {
+            this.maxPerRoute.put(route, max);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    public PoolStats getTotalStats() {
+        this.lock.lock();
+        try {
+            return new PoolStats(
+                    this.leasedSessions.size(),
+                    this.pendingSessions.size(),
+                    this.availableSessions.size(),
+                    this.maxTotal);
+        } finally {
+            this.lock.unlock();
+        }
+    }
+
+    public PoolStats getStats(final T route) {
+        this.lock.lock();
+        try {
+            SessionPoolForRoute<T> pool = getPool(route);
+            return new PoolStats(
+                    pool.getLeasedCount(),
+                    pool.getPendingCount(),
+                    pool.getAvailableCount(),
+                    getMaxPerRoute(route));
+        } finally {
+            this.lock.unlock();
+        }
+    }
+    
+    @Override
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("[leased: ");
+        buffer.append(this.leasedSessions.size());
+        buffer.append("][available: ");
+        buffer.append(this.availableSessions.size());
+        buffer.append("][pending: ");
+        buffer.append(this.pendingSessions.size());
+        buffer.append("]");
+        return super.toString();
+    }
+
+	class InternalSessionRequestCallback implements SessionRequestCallback {
+
+        public void completed(final SessionRequest request) {
+            requestCompleted(request);
+        }
+
+        public void cancelled(final SessionRequest request) {
+            requestCancelled(request);
+        }
+
+        public void failed(final SessionRequest request) {
+            requestFailed(request);
+        }
+
+        public void timeout(final SessionRequest request) {
+            requestTimeout(request);
+        }
+
+    }
+
+}

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

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPool.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

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

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPoolForRoute.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPoolForRoute.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPoolForRoute.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPoolForRoute.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,187 @@
+/*
+ * ====================================================================
+ * 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.net.SocketTimeoutException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.http.nio.reactor.IOSession;
+import org.apache.http.nio.reactor.SessionRequest;
+
+class SessionPoolForRoute<T> {
+
+    private final T route;
+    private final Set<PoolEntry<T>> leasedSessions;
+    private final LinkedList<PoolEntry<T>> availableSessions;
+    private final Map<SessionRequest, PoolEntryCallback<T>> pendingSessions;
+
+    public SessionPoolForRoute(final T route) {
+        super();
+        this.route = route;
+        this.leasedSessions = new HashSet<PoolEntry<T>>();
+        this.availableSessions = new LinkedList<PoolEntry<T>>();
+        this.pendingSessions = new HashMap<SessionRequest, PoolEntryCallback<T>>();
+    }
+
+    public int getLeasedCount() {
+        return this.leasedSessions.size();
+    }
+
+    public int getPendingCount() {
+        return this.pendingSessions.size();
+    }
+
+    public int getAvailableCount() {
+        return this.availableSessions.size();
+    }
+
+    public int getAllocatedCount() {
+        return this.availableSessions.size() + this.leasedSessions.size() + this.pendingSessions.size();
+    }
+
+    public PoolEntry<T> getFreeEntry(final Object state) {
+        if (!this.availableSessions.isEmpty()) {
+            ListIterator<PoolEntry<T>> it = this.availableSessions.listIterator(
+                    this.availableSessions.size());
+            while (it.hasPrevious()) {
+                PoolEntry<T> entry = it.previous();
+                IOSession iosession = entry.getIOSession();
+                if (iosession.isClosed()) {
+                    it.remove();
+                } else {
+                    if (entry.getState() == null || entry.getState().equals(state)) {
+                        it.remove();
+                        this.leasedSessions.add(entry);
+                        return entry;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    public PoolEntry<T> deleteLastUsed() {
+        return this.availableSessions.poll();
+    }
+
+    public boolean remove(final PoolEntry<T> entry) {
+        if (entry == null) {
+            throw new IllegalArgumentException("Pool entry may not be null");
+        }
+        boolean foundLeased = this.leasedSessions.remove(entry);
+        boolean foundFree = this.availableSessions.remove(entry);
+        return foundLeased || foundFree;
+    }
+
+    public void freeEntry(final PoolEntry<T> entry, boolean reusable) {
+        if (entry == null) {
+            throw new IllegalArgumentException("Pool entry may not be null");
+        }
+        boolean found = this.leasedSessions.remove(entry);
+        if (!found) {
+            throw new IllegalStateException("Entry " + entry +
+                    " has not been leased from this pool");
+        }
+        if (reusable) {
+            this.availableSessions.add(entry);
+        }
+    }
+
+    public void addPending(
+            final SessionRequest sessionRequest,
+            final PoolEntryCallback<T> callback) {
+        this.pendingSessions.put(sessionRequest, callback);
+    }
+
+    private PoolEntryCallback<T> removeRequest(final SessionRequest request) {
+        PoolEntryCallback<T> callback = this.pendingSessions.remove(request);
+        if (callback == null) {
+            throw new IllegalStateException("Invalid session request");
+        }
+        return callback;
+    }
+
+    public PoolEntry<T> completed(final SessionRequest request) {
+        PoolEntryCallback<T> callback = removeRequest(request);
+        IOSession iosession = request.getSession();
+        PoolEntry<T> entry = new PoolEntry<T>(this.route, iosession);
+        this.leasedSessions.add(entry);
+        callback.completed(entry);
+        return entry;
+    }
+
+    public void cancelled(final SessionRequest request) {
+        PoolEntryCallback<T> callback = removeRequest(request);
+        callback.cancelled();
+    }
+
+    public void failed(final SessionRequest request) {
+        PoolEntryCallback<T> callback = removeRequest(request);
+        callback.failed(request.getException());
+    }
+
+    public void timeout(final SessionRequest request) {
+        PoolEntryCallback<T> callback = removeRequest(request);
+        callback.failed(new SocketTimeoutException());
+    }
+
+    public void shutdown() {
+        for (SessionRequest sessionRequest: this.pendingSessions.keySet()) {
+            sessionRequest.cancel();
+        }
+        this.pendingSessions.clear();
+        for (PoolEntry<T> entry: this.availableSessions) {
+            entry.getIOSession().close();
+        }
+        this.availableSessions.clear();
+        for (PoolEntry<T> entry: this.leasedSessions) {
+            entry.getIOSession().close();
+        }
+        this.leasedSessions.clear();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("[route: ");
+        buffer.append(this.route);
+        buffer.append("][leased: ");
+        buffer.append(this.leasedSessions.size());
+        buffer.append("][available: ");
+        buffer.append(this.availableSessions.size());
+        buffer.append("][pending: ");
+        buffer.append(this.pendingSessions.size());
+        buffer.append("]");
+        return super.toString();
+    }
+
+}

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

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/impl/nio/pool/SessionPoolForRoute.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

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

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,43 @@
+/*
+ * ====================================================================
+ * 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.nio.client;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.nio.reactor.IOReactorStatus;
+
+public interface AsyncHttpClient {
+
+    void start();
+
+    void shutdown() throws InterruptedException;
+
+    IOReactorStatus getStatus();
+    
+    HttpExchange execute(HttpHost target, HttpRequest request);
+    
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/AsyncHttpClient.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,44 @@
+/*
+ * ====================================================================
+ * 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.nio.client;
+
+import java.util.concurrent.ExecutionException;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+
+public interface HttpExchange {
+
+    boolean isCompleted();
+
+    void cancel();
+    
+    HttpRequest getRequest();
+    
+    HttpResponse awaitResponse() throws ExecutionException, InterruptedException;
+    
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/client/HttpExchange.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,133 @@
+/*
+ * ====================================================================
+ * 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.nio.concurrent;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+public class BasicFuture<T> implements Future<T> {
+
+    private final FutureCallback<T> callback;
+
+    private volatile boolean completed;
+    private volatile boolean cancelled;
+    private volatile T result;
+    private volatile Exception ex;
+
+    public BasicFuture(final FutureCallback<T> callback) {
+        super();
+        this.callback = callback;
+    }
+
+    public boolean isCancelled() {
+        return this.cancelled;
+    }
+
+    public boolean isDone() {
+        return this.completed;
+    }
+
+    private T getResult() throws ExecutionException {
+        if (this.ex != null) {
+            throw new ExecutionException(this.ex);
+        }
+        return this.result;
+    }
+
+    public synchronized T get() throws InterruptedException, ExecutionException {
+        while (!this.completed) {
+            wait();
+        }
+        return getResult();
+    }
+
+    public synchronized T get(long timeout, final TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+        long msecs = unit.toMillis(timeout);
+        long startTime = (msecs <= 0) ? 0 : System.currentTimeMillis();
+        long waitTime = msecs;
+        if (this.completed) {
+            return getResult();
+        } else if (waitTime <= 0) {
+            throw new TimeoutException();
+        } else {
+            for (;;) {
+                wait(waitTime);
+                if (this.completed) {
+                    return getResult();
+                } else {
+                    waitTime = msecs - (System.currentTimeMillis() - startTime);
+                    if (waitTime <= 0) {
+                        throw new TimeoutException();
+                    }
+                }
+            }
+        }
+    }
+
+    public synchronized boolean completed(final T result) {
+        if (this.completed) {
+            return false;
+        }
+        this.completed = true;
+        this.result = result;
+        notifyAll();
+        if (this.callback != null) {
+            this.callback.completed(this);
+        }
+        return true;
+    }
+
+    public synchronized boolean failed(final Exception exception) {
+        if (this.completed) {
+            return false;
+        }
+        this.completed = true;
+        this.ex = exception;
+        notifyAll();
+        if (this.callback != null) {
+            this.callback.failed(this);
+        }
+        return true;
+    }
+
+    public synchronized boolean cancel(boolean mayInterruptIfRunning) {
+        if (this.completed) {
+            return false;
+        }
+        this.completed = true;
+        this.cancelled = true;
+        notifyAll();
+        if (this.callback != null) {
+            this.callback.cancelled(this);
+        }
+        return true;
+    }
+
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/BasicFuture.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java Sat Sep 12 20:30:20 2009
@@ -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.nio.concurrent;
+
+import java.util.concurrent.Future;
+
+public interface FutureCallback<T> {
+
+    void completed(Future<T> future);
+
+    void failed(Future<T> future);
+
+    void cancelled(Future<T> future);
+
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/concurrent/FutureCallback.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,42 @@
+/*
+ * ====================================================================
+ * 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.nio.conn;
+
+import java.util.concurrent.Future;
+
+import org.apache.http.nio.concurrent.FutureCallback;
+
+public interface IOSessionManager<T> {
+
+    Future<ManagedIOSession> leaseSession(
+            T route, Object state, FutureCallback<ManagedIOSession> callback);
+
+    void releaseSession(ManagedIOSession session);
+
+    void shutdown();
+
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/IOSessionManager.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,49 @@
+/*
+ * ====================================================================
+ * 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.nio.conn;
+
+import org.apache.http.nio.reactor.IOSession;
+
+public interface ManagedIOSession  {
+
+    IOSession getSession();
+
+    Object getState();
+
+    void setState(Object state);
+
+    void markReusable();
+
+    void markNonReusable();
+
+    boolean isReusable();
+
+    void releaseSession();
+
+    void abortSession();
+
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/ManagedIOSession.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java
URL: http://svn.apache.org/viewvc/httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java?rev=814229&view=auto
==============================================================================
--- httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java (added)
+++ httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java Sat Sep 12 20:30:20 2009
@@ -0,0 +1,75 @@
+/*
+ * ====================================================================
+ * 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.nio.conn;
+
+public class PoolStats {
+
+    private final int leased;
+    private final int pending;
+    private final int available;
+    private final int max;
+
+    public PoolStats(int leased, int pending, int free, int max) {
+        super();
+        this.leased = leased;
+        this.pending = pending;
+        this.available = free;
+        this.max = max;
+    }
+
+    public int getLeased() {
+        return this.leased;
+    }
+
+    public int getPending() {
+        return this.pending;
+    }
+
+    public int getAvailable() {
+        return this.available;
+    }
+
+    public int getMax() {
+        return this.max;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("[leased: ");
+        buffer.append(this.leased);
+        buffer.append("; pending: ");
+        buffer.append(this.pending);
+        buffer.append("; available: ");
+        buffer.append(this.available);
+        buffer.append("; max: ");
+        buffer.append(this.max);
+        buffer.append("]");
+        return buffer.toString();
+    }
+
+}

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: httpcomponents/asynchttpclient/trunk/src/main/java/org/apache/http/nio/conn/PoolStats.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain