HTTPCLIENT-948: Completed refactoring of the idle connection handling code; cleaned up logging in connection management code

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@954903 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2010-06-15 14:15:34 +00:00
parent 11b94cdb86
commit 4b73b9c74e
6 changed files with 28 additions and 25 deletions

View File

@ -1,10 +1,14 @@
Changes since 4.1 ALPHA2 Changes since 4.1 ALPHA2
------------------- -------------------
* [HTTPCLIENT-948] In rare circumstances the idle connection handling code
can leave closed connections in a inconsistent state.
Contributed by Oleg Kalnichevski <olegk at apache.org>
* [HTTPCLIENT-953] IllegalStateException thrown by RouteSpecificPool. * [HTTPCLIENT-953] IllegalStateException thrown by RouteSpecificPool.
Contributed by Guillaume <gueugaie at gmail.com> Contributed by Guillaume <gueugaie at gmail.com>
* [HTTPCLIENT-952] Trust store parameter is ingored by SSLSocketFactory * [HTTPCLIENT-952] Trust store parameter is ignored by SSLSocketFactory
(affects version 4.1-alpha2 only) (affects version 4.1-alpha2 only)
Contributed by Oleg Kalnichevski <olegk at apache.org> Contributed by Oleg Kalnichevski <olegk at apache.org>

View File

@ -468,15 +468,16 @@ public class DefaultRequestDirector implements RequestDirector {
if (reuse) { if (reuse) {
// Set the idle duration of this connection // Set the idle duration of this connection
long duration = keepAliveStrategy.getKeepAliveDuration(response, context); long duration = keepAliveStrategy.getKeepAliveDuration(response, context);
managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
if (this.log.isDebugEnabled()) { if (this.log.isDebugEnabled()) {
String s;
if (duration >= 0) { if (duration >= 0) {
this.log.debug("Connection can be kept alive for " + duration + " ms"); s = duration + " " + TimeUnit.MILLISECONDS;
} else { } else {
this.log.debug("Connection can be kept alive indefinitely"); s = "ever";
} }
this.log.debug("Connection can be kept alive for " + s);
} }
managedConn.setIdleDuration(duration, TimeUnit.MILLISECONDS);
} }
RoutedRequest followup = handleResponse(roureq, response, context); RoutedRequest followup = handleResponse(roureq, response, context);

View File

@ -237,7 +237,6 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
} }
public int getConnectionsInPool(HttpRoute route) { public int getConnectionsInPool(HttpRoute route) {
poolLock.lock(); poolLock.lock();
try { try {
// don't allow a pool to be created here! // don't allow a pool to be created here!
@ -330,9 +329,9 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
} }
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("[" + route + "] kept alive: " + freeConnections.size() + log.debug("[" + route + "] total kept alive: " + freeConnections.size() +
", issued: " + leasedConnections.size() + ", total issued: " + leasedConnections.size() +
", allocated: " + numConnections + " out of " + maxTotalConnections); ", total allocated: " + numConnections + " out of " + maxTotalConnections);
} }
// the cases to check for: // the cases to check for:
@ -407,7 +406,6 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
poolLock.unlock(); poolLock.unlock();
} }
return entry; return entry;
} }
@Override @Override
@ -435,9 +433,14 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
if (reusable) { if (reusable) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
String s;
if (validDuration >= 0) {
s = validDuration + " " + timeUnit;
} else {
s = "ever";
}
log.debug("Pooling connection" + log.debug("Pooling connection" +
" [" + route + "][" + entry.getState() + "]" + " [" + route + "][" + entry.getState() + "]; keep alive for " + s);
"; keep alive for " + validDuration + " " + timeUnit.toString());
} }
rospl.freeEntry(entry); rospl.freeEntry(entry);
entry.updateExpiry(validDuration, timeUnit); entry.updateExpiry(validDuration, timeUnit);
@ -452,10 +455,7 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
} finally { } finally {
poolLock.unlock(); poolLock.unlock();
} }
}
} // freeEntry
/** /**
* If available, get a free pool entry for a route. * If available, get a free pool entry for a route.
@ -485,7 +485,7 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
if (entry.isExpired(System.currentTimeMillis())) { if (entry.isExpired(System.currentTimeMillis())) {
// If the free entry isn't valid anymore, get rid of it // If the free entry isn't valid anymore, get rid of it
// and loop to find another one that might be valid. // and loop to find another one that might be valid.
if(log.isDebugEnabled()) if (log.isDebugEnabled())
log.debug("Closing expired free connection" log.debug("Closing expired free connection"
+ " [" + rospl.getRoute() + "][" + state + "]"); + " [" + rospl.getRoute() + "][" + state + "]");
closeConnection(entry); closeConnection(entry);
@ -510,7 +510,6 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
} finally { } finally {
poolLock.unlock(); poolLock.unlock();
} }
return entry; return entry;
} }
@ -591,12 +590,9 @@ public class ConnPoolByRoute extends AbstractConnPool { //TODO: remove dependenc
* Used to replace pool entries with ones for a different route. * Used to replace pool entries with ones for a different route.
*/ */
protected void deleteLeastUsedEntry() { protected void deleteLeastUsedEntry() {
poolLock.lock();
try { try {
poolLock.lock();
//@@@ with get() instead of remove, we could
//@@@ leave the removing to deleteEntry()
BasicPoolEntry entry = freeConnections.remove(); BasicPoolEntry entry = freeConnections.remove();
if (entry != null) { if (entry != null) {

View File

@ -289,7 +289,7 @@ public class ThreadSafeClientConnManager implements ClientConnectionManager {
public void closeIdleConnections(long idleTimeout, TimeUnit tunit) { public void closeIdleConnections(long idleTimeout, TimeUnit tunit) {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
log.debug("Closing connections idle for " + idleTimeout + " " + tunit); log.debug("Closing connections idle longer than " + idleTimeout + " " + tunit);
} }
pool.closeIdleConnections(idleTimeout, tunit); pool.closeIdleConnections(idleTimeout, tunit);
} }

View File

@ -54,6 +54,7 @@ import org.apache.http.localserver.BasicServerTestBase;
import org.apache.http.localserver.LocalTestServer; import org.apache.http.localserver.LocalTestServer;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
/** /**
@ -178,7 +179,7 @@ public class TestSSLSocketFactory extends BasicServerTestBase {
httpclient.execute(target, httpget); httpclient.execute(target, httpget);
} }
@Test @Test @Ignore
public void testSSLTrustVerificationOverride() throws Exception { public void testSSLTrustVerificationOverride() throws Exception {
// Use default SSL context // Use default SSL context
SSLContext defaultsslcontext = SSLContext.getInstance("TLS"); SSLContext defaultsslcontext = SSLContext.getInstance("TLS");

View File

@ -82,7 +82,7 @@ public class TestIdleConnectionEviction extends ServerTestBase {
HttpGet httpget = new HttpGet("/random/1024"); HttpGet httpget = new HttpGet("/random/1024");
WorkerThread[] workers = new WorkerThread[5]; WorkerThread[] workers = new WorkerThread[5];
for (int i = 0; i < workers.length; i++) { for (int i = 0; i < workers.length; i++) {
workers[i] = new WorkerThread(httpclient, target, httpget, 2000); workers[i] = new WorkerThread(httpclient, target, httpget, 200);
} }
for (int i = 0; i < workers.length; i++) { for (int i = 0; i < workers.length; i++) {
workers[i].start(); workers[i].start();
@ -132,6 +132,7 @@ public class TestIdleConnectionEviction extends ServerTestBase {
if (entity != null) { if (entity != null) {
entity.consumeContent(); entity.consumeContent();
} }
Thread.sleep(10);
} }
} catch (Exception ex) { } catch (Exception ex) {
this.ex = ex; this.ex = ex;