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 2013/06/13 15:54:54 UTC
svn commit: r1492676 - in /httpcomponents/httpasyncclient/trunk: ./
httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/
Author: olegk
Date: Thu Jun 13 13:54:53 2013
New Revision: 1492676
URL: http://svn.apache.org/r1492676
Log:
HTTPASYNC-45: CachingHttpAsyncClient to override Future returned by the backend.
Contributed by James Leigh <james at 3roundstones dot com>
Added:
httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java (with props)
Modified:
httpcomponents/httpasyncclient/trunk/RELEASE_NOTES.txt
httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpAsyncClient.java
Modified: httpcomponents/httpasyncclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/RELEASE_NOTES.txt?rev=1492676&r1=1492675&r2=1492676&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpasyncclient/trunk/RELEASE_NOTES.txt Thu Jun 13 13:54:53 2013
@@ -1,3 +1,10 @@
+Change since Release 4.0 Beta 4
+-------------------
+
+* [HTTPASYNC-45] CachingHttpAsyncClient to override Future returned by the backend.
+ Contributed by James Leigh <james at 3roundstones dot com>
+
+
Release 4.0 Beta 4
-------------------
Modified: httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpAsyncClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpAsyncClient.java?rev=1492676&r1=1492675&r2=1492676&view=diff
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpAsyncClient.java (original)
+++ httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpAsyncClient.java Thu Jun 13 13:54:53 2013
@@ -78,6 +78,7 @@ import org.apache.http.params.HttpParams
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Args;
+import org.apache.http.util.EntityUtils;
import org.apache.http.util.VersionInfo;
@SuppressWarnings("deprecation")
@@ -400,24 +401,17 @@ public class CachingHttpAsyncClient impl
future.completed(resp);
return future;
}
- return revalidateCacheEntry(target, request, context, entry, new FutureCallback<HttpResponse> () {
-
- public void cancelled() {
- futureCallback.cancelled();
- }
-
- public void completed(final HttpResponse httpResponse) {
- futureCallback.completed(httpResponse);
- }
-
- public void failed(final Exception e) {
- if(e instanceof IOException) {
- futureCallback.completed(handleRevalidationFailure(request, context, entry, now));
- return;
+ final FutureHttpResponse future = new FutureHttpResponse(futureCallback) {
+ public void failed(final Exception ex) {
+ if(ex instanceof IOException) {
+ super.completed(handleRevalidationFailure(request, context, entry, now));
+ } else {
+ super.failed(ex);
}
- futureCallback.failed(e);
}
- });
+ };
+ future.setDelegate(revalidateCacheEntry(target, request, context, entry, future));
+ return future;
} catch (final ProtocolException e) {
throw new ClientProtocolException(e);
}
@@ -662,30 +656,21 @@ public class CachingHttpAsyncClient impl
final HttpHost target, final HttpRequestWrapper request, final HttpContext context,
final FutureCallback<HttpResponse> futureCallback) {
final Date requestDate = getCurrentDate();
- this.log.debug("Calling the backend");
- return this.backend.execute(target, request, context, new FutureCallback<HttpResponse>() {
-
- public void cancelled() {
- futureCallback.cancelled();
- }
-
+ this.log.trace("Calling the backend");
+ final FutureHttpResponse future = new FutureHttpResponse(futureCallback) {
public void completed(final HttpResponse httpResponse) {
- httpResponse.addHeader("Via", generateViaHeader(httpResponse));
+ httpResponse.addHeader(HeaderConstants.VIA, generateViaHeader(httpResponse));
try {
final HttpResponse backendResponse = handleBackendResponse(target, request, requestDate, getCurrentDate(), httpResponse);
- futureCallback.completed(backendResponse);
+ super.completed(backendResponse);
} catch (final IOException e) {
- futureCallback.failed(e);
- return;
+ super.failed(e);
}
}
-
- public void failed(final Exception e) {
- futureCallback.failed(e);
- }
-
- });
+ };
+ future.setDelegate(this.backend.execute(target, request, context, future));
+ return future;
}
private boolean revalidationResponseIsTooOld(final HttpResponse backendResponse,
@@ -716,11 +701,11 @@ public class CachingHttpAsyncClient impl
final HttpRequest conditionalRequest = this.conditionalRequestBuilder.buildConditionalRequestFromVariants(request, variants);
final Date requestDate = getCurrentDate();
- //HttpResponse backendResponse =
- return this.backend.execute(target, conditionalRequest, new FutureCallback<HttpResponse> () {
+ final FutureHttpResponse future = new FutureHttpResponse(futureCallback);
+ Future<HttpResponse> backendFuture = this.backend.execute(target, conditionalRequest, context, new FutureCallback<HttpResponse> () {
public void cancelled() {
- futureCallback.cancelled();
+ future.cancelled();
}
public void completed(final HttpResponse httpResponse) {
@@ -730,11 +715,10 @@ public class CachingHttpAsyncClient impl
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_NOT_MODIFIED) {
try {
- final HttpResponse backendResponse = handleBackendResponse(target, request, requestDate, responseDate, httpResponse);
- futureCallback.completed(backendResponse);
+ future.completed(handleBackendResponse(target, request, requestDate, responseDate, httpResponse));
return;
} catch (final IOException e) {
- futureCallback.failed(e);
+ future.failed(e);
return;
}
}
@@ -742,21 +726,7 @@ public class CachingHttpAsyncClient impl
final Header resultEtagHeader = httpResponse.getFirstHeader(HeaderConstants.ETAG);
if (resultEtagHeader == null) {
CachingHttpAsyncClient.this.log.warn("304 response did not contain ETag");
- callBackend(target, request, context, new FutureCallback<HttpResponse>() {
-
- public void cancelled() {
- futureCallback.cancelled();
- }
-
- public void completed(final HttpResponse innerHttpResponse) {
- futureCallback.completed(innerHttpResponse);
- }
-
- public void failed(final Exception e) {
- futureCallback.failed(e);
- }
-
- });
+ callBackend(target, request, context, future);
return;
}
@@ -764,27 +734,14 @@ public class CachingHttpAsyncClient impl
final Variant matchingVariant = variants.get(resultEtag);
if (matchingVariant == null) {
CachingHttpAsyncClient.this.log.debug("304 response did not contain ETag matching one sent in If-None-Match");
- callBackend(target, request, context, new FutureCallback<HttpResponse>() {
-
- public void cancelled() {
- futureCallback.cancelled();
- }
-
- public void completed(final HttpResponse innerHttpResponse) {
- futureCallback.completed(innerHttpResponse);
- }
-
- public void failed(final Exception e) {
- futureCallback.failed(e);
- }
-
- });
+ callBackend(target, request, context, future);
}
final HttpCacheEntry matchedEntry = matchingVariant.getEntry();
if (revalidationResponseIsTooOld(httpResponse, matchedEntry)) {
- retryRequestUnconditionally(target, request, context, matchedEntry, futureCallback);
+ EntityUtils.consumeQuietly(httpResponse.getEntity());
+ retryRequestUnconditionally(target, request, context, matchedEntry, future);
return;
}
@@ -798,20 +755,20 @@ public class CachingHttpAsyncClient impl
tryToUpdateVariantMap(target, request, matchingVariant);
if (shouldSendNotModifiedResponse(request, responseEntry)) {
- final HttpResponse backendResponse = CachingHttpAsyncClient.this.responseGenerator.generateNotModifiedResponse(responseEntry);
- futureCallback.completed(backendResponse);
+ future.completed(CachingHttpAsyncClient.this.responseGenerator.generateNotModifiedResponse(responseEntry));
return;
}
- final HttpResponse backendResponse = resp;
- futureCallback.completed(backendResponse);
+ future.completed(resp);
return;
}
- public void failed(final Exception e) {
- futureCallback.failed(e);
+ public void failed(final Exception ex) {
+ future.failed(ex);
}
});
+ future.setDelegate(backendFuture);
+ return future;
}
private void retryRequestUnconditionally(final HttpHost target,
@@ -860,10 +817,11 @@ public class CachingHttpAsyncClient impl
final HttpRequestWrapper conditionalRequest = this.conditionalRequestBuilder.buildConditionalRequest(request, cacheEntry);
final Date requestDate = getCurrentDate();
- return this.backend.execute(target, conditionalRequest, context, new FutureCallback<HttpResponse>() {
+ final FutureHttpResponse future = new FutureHttpResponse(futureCallback);
+ future.setDelegate(this.backend.execute(target, conditionalRequest, context, new FutureCallback<HttpResponse>() {
public void cancelled() {
- futureCallback.cancelled();
+ future.cancelled();
}
public void completed(final HttpResponse httpResponse) {
@@ -875,35 +833,36 @@ public class CachingHttpAsyncClient impl
CachingHttpAsyncClient.this.backend.execute(target, unconditional, context, new FutureCallback<HttpResponse>() {
public void cancelled() {
- futureCallback.cancelled();
+ future.cancelled();
}
public void completed(final HttpResponse innerHttpResponse) {
final Date innerResponseDate = getCurrentDate();
revalidateCacheEntryCompleted(target, request,
- context, cacheEntry, futureCallback,
+ context, cacheEntry, future,
conditionalRequest, innerRequestDate,
innerHttpResponse, innerResponseDate);
}
- public void failed(final Exception e) {
- futureCallback.failed(e);
+ public void failed(final Exception ex) {
+ future.failed(ex);
}
});
return;
}
revalidateCacheEntryCompleted(target, request,
- context, cacheEntry, futureCallback,
+ context, cacheEntry, future,
conditionalRequest, requestDate,
httpResponse, responseDate);
}
- public void failed(final Exception e) {
- futureCallback.failed(e);
+ public void failed(final Exception ex) {
+ future.failed(ex);
}
- });
+ }));
+ return future;
}
private void revalidateCacheEntryCompleted(
@@ -911,7 +870,7 @@ public class CachingHttpAsyncClient impl
final HttpRequestWrapper request,
final HttpContext context,
final HttpCacheEntry cacheEntry,
- final FutureCallback<HttpResponse> futureCallback,
+ final FutureHttpResponse futureCallback,
final HttpRequestWrapper conditionalRequest,
final Date requestDate,
final HttpResponse httpResponse,
Added: httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java?rev=1492676&view=auto
==============================================================================
--- httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java (added)
+++ httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java Thu Jun 13 13:54:53 2013
@@ -0,0 +1,151 @@
+/*
+ * ====================================================================
+ * 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.client.cache;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.concurrent.FutureCallback;
+
+/**
+ * Implementation that wraps a Future and overrides the result/exception.
+ *
+ * @author James Leigh
+ *
+ */
+class FutureHttpResponse implements Future<HttpResponse>,
+ FutureCallback<HttpResponse> {
+ private final FutureCallback<HttpResponse> callback;
+ private Future<HttpResponse> delegate;
+ private HttpResponse response;
+ private Throwable thrown;
+
+ public FutureHttpResponse(FutureCallback<HttpResponse> callback) {
+ this.callback = callback;
+ }
+
+ public String toString() {
+ return String.valueOf(response);
+ }
+
+ public synchronized Future<HttpResponse> getDelegate() {
+ return delegate;
+ }
+
+ public synchronized void setDelegate(Future<HttpResponse> delegate) {
+ this.delegate = delegate;
+ }
+
+ public boolean isCancelled() {
+ Future<?> delegate = getDelegate();
+ return delegate != null && delegate.isCancelled();
+ }
+
+ public boolean isDone() {
+ Future<?> delegate = getDelegate();
+ return delegate != null && getDelegate().isDone();
+ }
+
+ public HttpResponse get() throws InterruptedException, ExecutionException {
+ try {
+ getDelegate().get();
+ } catch (ExecutionException e) {
+ // ignore
+ }
+ HttpResponse result = getResponse();
+ Throwable thrown = getThrown();
+ if (thrown != null)
+ throw new ExecutionException(thrown);
+ return result;
+ }
+
+ public HttpResponse get(long timeout, TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ try {
+ getDelegate().get(timeout, unit);
+ } catch (ExecutionException e) {
+ // ignore
+ }
+ HttpResponse result = getResponse();
+ Throwable thrown = getThrown();
+ if (thrown != null)
+ throw new ExecutionException(thrown);
+ return result;
+ }
+
+ public void completed(final HttpResponse result) {
+ setResponse(result);
+ if (this.callback != null) {
+ this.callback.completed(result);
+ }
+ }
+
+ public void failed(final Exception exception) {
+ setThrown(exception);
+ if (this.callback != null) {
+ this.callback.failed(exception);
+ }
+ }
+
+ public boolean cancel(final boolean mayInterruptIfRunning) {
+ if (this.callback != null) {
+ this.callback.cancelled();
+ }
+ return getDelegate().cancel(mayInterruptIfRunning);
+ }
+
+ public boolean cancel() {
+ return cancel(true);
+ }
+
+ @Override
+ public void cancelled() {
+ if (this.callback != null) {
+ this.callback.cancelled();
+ }
+ }
+
+ private synchronized HttpResponse getResponse() {
+ return response;
+ }
+
+ private synchronized void setResponse(HttpResponse response) {
+ this.response = response;
+ }
+
+ private synchronized Throwable getThrown() {
+ return thrown;
+ }
+
+ private synchronized void setThrown(Throwable thrown) {
+ this.thrown = thrown;
+ }
+
+}
Propchange: httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpasyncclient/trunk/httpasyncclient-cache/src/main/java/org/apache/http/impl/client/cache/FutureHttpResponse.java
------------------------------------------------------------------------------
svn:mime-type = text/plain