Author: rvesse
Date: Fri Aug 9 17:30:40 2013
New Revision: 1512409
URL: http://svn.apache.org/r1512409
Log:
Take care to recycle HttpClient's created in QueryEngineHTTP (JENA-498)
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/HttpQuery.java
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/QueryEngineHTTP.java
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/HttpQuery.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/HttpQuery.java?rev=1512409&r1=1512408&r2=1512409&view=diff
==============================================================================
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/HttpQuery.java
(original)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/HttpQuery.java
Fri Aug 9 17:30:40 2013
@@ -21,9 +21,11 @@ package com.hp.hpl.jena.sparql.engine.ht
import java.io.InputStream ;
import java.net.MalformedURLException ;
import java.net.URL ;
+import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern ;
import org.apache.http.client.HttpClient ;
+import org.apache.http.conn.params.ConnManagerPNames;
import org.apache.http.impl.client.AbstractHttpClient ;
import org.apache.http.impl.client.DecompressingHttpClient ;
import org.apache.http.impl.client.SystemDefaultHttpClient ;
@@ -73,6 +75,7 @@ public class HttpQuery extends Params {
private int connectTimeout = 0, readTimeout = 0;
private boolean allowGZip = false;
private boolean allowDeflate = false;
+ private HttpClient client;
// static final String ENC_UTF8 = "UTF-8" ;
@@ -191,6 +194,14 @@ public class HttpQuery extends Params {
public void setAuthenticator(HttpAuthenticator authenticator) {
this.authenticator = authenticator;
}
+
+ /**
+ * Gets the HTTP client that is being used, may be null if no request has
yet been made
+ * @return HTTP Client or null
+ */
+ public HttpClient getClient() {
+ return this.client;
+ }
/**
* Return whether this request will go by GET or POST
@@ -271,6 +282,7 @@ public class HttpQuery extends Params {
}
}
+ @SuppressWarnings("deprecation")
private InputStream execGet() throws QueryExceptionHTTP {
URL target = null;
String qs = getQueryString();
@@ -289,11 +301,19 @@ public class HttpQuery extends Params {
try {
try {
- HttpClient client = new SystemDefaultHttpClient();
+ this.client = new SystemDefaultHttpClient();
+
+ // Always apply a 10 second timeout to obtaining a connection
lease from HTTP Client
+ // This prevents a potential lock up
+
this.client.getParams().setLongParameter(ConnManagerPNames.TIMEOUT,
TimeUnit.SECONDS.toMillis(10));
+
+ // If user has specified time outs apply them now
if (this.connectTimeout > 0)
-
client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
this.connectTimeout);
+
this.client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
this.connectTimeout);
if (this.readTimeout > 0)
-
client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
this.readTimeout);
+
this.client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
this.readTimeout);
+
+ // Enable compression support appropriately
HttpContext context = new BasicHttpContext();
if (allowGZip || allowDeflate) {
// Apply auth early as the decompressing client we're about
@@ -301,6 +321,8 @@ public class HttpQuery extends Params {
HttpOp.applyAuthentication((AbstractHttpClient) client,
serviceURL, context, authenticator);
client = new DecompressingHttpClient(client);
}
+
+ // Get the actual response stream
TypedInputStream stream =
HttpOp.execHttpGet(target.toString(), contentTypeResult, client, context,
this.authenticator);
if (stream == null)
@@ -319,6 +341,7 @@ public class HttpQuery extends Params {
}
}
+ @SuppressWarnings("deprecation")
private InputStream execPost() throws QueryExceptionHTTP {
URL target = null;
try {
@@ -331,19 +354,28 @@ public class HttpQuery extends Params {
ARQ.getHttpRequestLogger().trace(target.toExternalForm());
try {
- HttpClient client = new SystemDefaultHttpClient();
+ this.client = new SystemDefaultHttpClient();
+
+ // Always apply a 10 second timeout to obtaining a connection
lease from HTTP Client
+ // This prevents a potential lock up
+
this.client.getParams().setLongParameter(ConnManagerPNames.TIMEOUT,
TimeUnit.SECONDS.toMillis(10));
+
+ // If user has specified time outs apply them now
if (this.connectTimeout > 0)
-
client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
this.connectTimeout);
+
this.client.getParams().setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,
this.connectTimeout);
if (this.readTimeout > 0)
-
client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
this.readTimeout);
+
this.client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,
this.readTimeout);
+
+ // Enable compression support appropriately
HttpContext context = new BasicHttpContext();
if (allowGZip || allowDeflate) {
// Apply auth early as the decompressing client we're about
// to add will block this being applied later
HttpOp.applyAuthentication((AbstractHttpClient) client,
serviceURL, context, authenticator);
- client = new DecompressingHttpClient(client);
+ this.client = new DecompressingHttpClient(client);
}
+ // Get the actual response stream
TypedInputStream stream =
HttpOp.execHttpPostFormStream(serviceURL, this, contentTypeResult, client,
context, authenticator);
if (stream == null)
throw new QueryExceptionHTTP(404);
Modified:
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/QueryEngineHTTP.java
URL:
http://svn.apache.org/viewvc/jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/QueryEngineHTTP.java?rev=1512409&r1=1512408&r2=1512409&view=diff
==============================================================================
---
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/QueryEngineHTTP.java
(original)
+++
jena/trunk/jena-arq/src/main/java/com/hp/hpl/jena/sparql/engine/http/QueryEngineHTTP.java
Fri Aug 9 17:30:40 2013
@@ -26,6 +26,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
+import org.apache.http.client.HttpClient;
import org.apache.jena.atlas.io.IO;
import org.apache.jena.atlas.web.auth.HttpAuthenticator;
import org.apache.jena.atlas.web.auth.SimpleAuthenticator;
@@ -100,6 +101,8 @@ public class QueryEngineHTTP implements
// and will close when the engine is closed
private InputStream retainedConnection = null;
+ private HttpClient retainedClient;
+
public QueryEngineHTTP(String serviceURI, Query query) {
this(serviceURI, query, query.toString());
}
@@ -350,6 +353,7 @@ public class QueryEngineHTTP implements
}
retainedConnection = in; // This will be closed on close()
+ retainedClient = httpQuery.getClient();
// TODO: Find a way to auto-detect how to create the ResultSet based on
// the content type in use
@@ -668,6 +672,15 @@ public class QueryEngineHTTP implements
retainedConnection = null;
}
}
+ if (retainedClient != null) {
+ try {
+ retainedClient.getConnectionManager().shutdown();
+ } catch (RuntimeException e) {
+ log.warn("Failed to shutdown HTTP client", e);
+ } finally {
+ retainedClient = null;
+ }
+ }
}
// public boolean isActive() { return false ; }