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/01/24 12:05:36 UTC
svn commit: r1437952 - in /httpcomponents/httpclient/trunk: ./
httpclient-cache/src/main/java/org/apache/http/impl/client/cache/
httpclient-cache/src/test/java/org/apache/http/impl/client/cache/
Author: olegk
Date: Thu Jan 24 11:05:36 2013
New Revision: 1437952
URL: http://svn.apache.org/viewvc?rev=1437952&view=rev
Log:
HTTPCLIENT-1298: Add AsynchronousValidator in HttpClientBuilder's list of closeable objects
Contributed by Martin Meinhold <mmeinhold at atlassian.com>
* Resolve constructor dependency between CachingExec and AsynchronousValidator
* AsynchronousValidator implements Closeable interface
Modified:
httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.java
httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java
httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.java
httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.java
Modified: httpcomponents/httpclient/trunk/RELEASE_NOTES.txt
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/RELEASE_NOTES.txt?rev=1437952&r1=1437951&r2=1437952&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/RELEASE_NOTES.txt (original)
+++ httpcomponents/httpclient/trunk/RELEASE_NOTES.txt Thu Jan 24 11:05:36 2013
@@ -1,3 +1,11 @@
+Changes since 4.3 ALPHA1
+-------------------
+
+* [HTTPCLIENT-1298] Add AsynchronousValidator in HttpClientBuilder's list of closeable objects.
+ Contributed by Martin Meinhold <mmeinhold at atlassian.com>
+
+
+
Release 4.3 ALPHA1
-------------------
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.java?rev=1437952&r1=1437951&r2=1437952&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/AsynchronousValidator.java Thu Jan 24 11:05:36 2013
@@ -26,6 +26,8 @@
*/
package org.apache.http.impl.client.cache;
+import java.io.Closeable;
+import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -47,8 +49,7 @@ import org.apache.http.conn.routing.Http
* Class used for asynchronous revalidations to be used when the "stale-
* while-revalidate" directive is present
*/
-class AsynchronousValidator {
- private final CachingExec cachingExec;
+class AsynchronousValidator implements Closeable {
private final ExecutorService executor;
private final Set<String> queued;
private final CacheKeyGenerator cacheKeyGenerator;
@@ -57,20 +58,16 @@ class AsynchronousValidator {
/**
* Create AsynchronousValidator which will make revalidation requests
- * using the supplied {@link CachingHttpClient}, and
- * a {@link ThreadPoolExecutor} generated according to the thread
+ * using a {@link ThreadPoolExecutor} generated according to the thread
* pool settings provided in the given {@link CacheConfig}.
- * @param cachingExect used to execute asynchronous requests
* @param config specifies thread pool settings. See
* {@link CacheConfig#getAsynchronousWorkersMax()},
* {@link CacheConfig#getAsynchronousWorkersCore()},
* {@link CacheConfig#getAsynchronousWorkerIdleLifetimeSecs()},
* and {@link CacheConfig#getRevalidationQueueSize()}.
*/
- public AsynchronousValidator(final CachingExec cachingExect,
- final CacheConfig config) {
- this(cachingExect,
- new ThreadPoolExecutor(config.getAsynchronousWorkersCore(),
+ public AsynchronousValidator(final CacheConfig config) {
+ this(new ThreadPoolExecutor(config.getAsynchronousWorkersCore(),
config.getAsynchronousWorkersMax(),
config.getAsynchronousWorkerIdleLifetimeSecs(),
TimeUnit.SECONDS,
@@ -82,20 +79,24 @@ class AsynchronousValidator {
* Create AsynchronousValidator which will make revalidation requests
* using the supplied {@link CachingHttpClient} and
* {@link ExecutorService}.
- * @param cachingExect used to execute asynchronous requests
* @param executor used to manage a thread pool of revalidation workers
*/
- AsynchronousValidator(final CachingExec cachingExec, final ExecutorService executor) {
- this.cachingExec = cachingExec;
+ AsynchronousValidator(final ExecutorService executor) {
this.executor = executor;
this.queued = new HashSet<String>();
this.cacheKeyGenerator = new CacheKeyGenerator();
}
+ @Override
+ public void close() throws IOException {
+ executor.shutdown();
+ }
+
/**
* Schedules an asynchronous revalidation
*/
public synchronized void revalidateCacheEntry(
+ final CachingExec cachingExec,
final HttpRoute route,
final HttpRequestWrapper request,
final HttpClientContext context,
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java?rev=1437952&r1=1437951&r2=1437952&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingExec.java Thu Jan 24 11:05:36 2013
@@ -119,6 +119,14 @@ public class CachingExec implements Clie
final ClientExecChain backend,
final HttpCache cache,
final CacheConfig config) {
+ this(backend, cache, config, null);
+ }
+
+ public CachingExec(
+ final ClientExecChain backend,
+ final HttpCache cache,
+ final CacheConfig config,
+ final AsynchronousValidator asynchRevalidator) {
super();
Args.notNull(backend, "HTTP backend");
Args.notNull(cache, "HttpCache");
@@ -135,7 +143,7 @@ public class CachingExec implements Clie
this.responseCachingPolicy = new ResponseCachingPolicy(
this.cacheConfig.getMaxObjectSize(), this.cacheConfig.isSharedCache(),
this.cacheConfig.isNeverCacheHTTP10ResponsesWithQuery());
- this.asynchRevalidator = makeAsynchronousValidator(config);
+ this.asynchRevalidator = asynchRevalidator != null ? asynchRevalidator : makeAsynchronousValidator(config);
}
public CachingExec(
@@ -179,7 +187,7 @@ public class CachingExec implements Clie
private AsynchronousValidator makeAsynchronousValidator(
final CacheConfig config) {
if (config.getAsynchronousWorkersMax() > 0) {
- return new AsynchronousValidator(this, config);
+ return new AsynchronousValidator(config);
}
return null;
}
@@ -312,7 +320,7 @@ public class CachingExec implements Clie
&& validityPolicy.mayReturnStaleWhileRevalidating(entry, now)) {
log.trace("Serving stale with asynchronous revalidation");
final HttpResponse resp = generateCachedResponse(request, context, entry, now);
- asynchRevalidator.revalidateCacheEntry(route, request, context, execAware, entry);
+ asynchRevalidator.revalidateCacheEntry(this, route, request, context, execAware, entry);
return Proxies.enhanceResponse(resp);
}
return revalidateCacheEntry(route, request, context, execAware, entry);
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.java?rev=1437952&r1=1437951&r2=1437952&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CachingHttpClientBuilder.java Thu Jan 24 11:05:36 2013
@@ -97,8 +97,15 @@ public class CachingHttpClientBuilder ex
}
storage = new BasicHttpCacheStorage(cacheConfig);
}
+ final AsynchronousValidator revalidator = createAsynchronousRevalidator(config);
return new CachingExec(mainExec,
- new BasicHttpCache(resourceFactory, storage, config), config);
+ new BasicHttpCache(resourceFactory, storage, config), config, revalidator);
+ }
+
+ private AsynchronousValidator createAsynchronousRevalidator(final CacheConfig config) {
+ final AsynchronousValidator revalidator = new AsynchronousValidator(config);
+ addCloseable(revalidator);
+ return revalidator;
}
}
Modified: httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.java?rev=1437952&r1=1437951&r2=1437952&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestAsynchronousValidator.java Thu Jan 24 11:05:36 2013
@@ -26,6 +26,7 @@
*/
package org.apache.http.impl.client.cache;
+import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
@@ -74,13 +75,13 @@ public class TestAsynchronousValidator {
@Test
public void testRevalidateCacheEntrySchedulesExecutionAndPopulatesIdentifier() {
- impl = new AsynchronousValidator(mockClient, mockExecutor);
+ impl = new AsynchronousValidator(mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
replayMocks();
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
@@ -88,14 +89,14 @@ public class TestAsynchronousValidator {
@Test
public void testMarkCompleteRemovesIdentifier() {
- impl = new AsynchronousValidator(mockClient, mockExecutor);
+ impl = new AsynchronousValidator(mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
final Capture<AsynchronousValidationRequest> cap = new Capture<AsynchronousValidationRequest>();
mockExecutor.execute(EasyMock.capture(cap));
replayMocks();
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
@@ -107,14 +108,14 @@ public class TestAsynchronousValidator {
@Test
public void testRevalidateCacheEntryDoesNotPopulateIdentifierOnRejectedExecutionException() {
- impl = new AsynchronousValidator(mockClient, mockExecutor);
+ impl = new AsynchronousValidator(mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
EasyMock.expectLastCall().andThrow(new RejectedExecutionException());
replayMocks();
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
verifyMocks();
Assert.assertEquals(0, impl.getScheduledIdentifiers().size());
@@ -122,7 +123,7 @@ public class TestAsynchronousValidator {
@Test
public void testRevalidateCacheEntryProperlyCollapsesRequest() {
- impl = new AsynchronousValidator(mockClient, mockExecutor);
+ impl = new AsynchronousValidator(mockExecutor);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
mockExecutor.execute(EasyMock.isA(AsynchronousValidationRequest.class));
@@ -130,8 +131,8 @@ public class TestAsynchronousValidator {
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
replayMocks();
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
verifyMocks();
Assert.assertEquals(1, impl.getScheduledIdentifiers().size());
@@ -139,7 +140,7 @@ public class TestAsynchronousValidator {
@Test
public void testVariantsBothRevalidated() {
- impl = new AsynchronousValidator(mockClient, mockExecutor);
+ impl = new AsynchronousValidator(mockExecutor);
final HttpRequest req1 = new HttpGet("/");
req1.addHeader(new BasicHeader("Accept-Encoding", "identity"));
@@ -157,8 +158,8 @@ public class TestAsynchronousValidator {
EasyMock.expectLastCall().times(2);
replayMocks();
- impl.revalidateCacheEntry(route, HttpRequestWrapper.wrap(req1), context, mockExecAware, mockCacheEntry);
- impl.revalidateCacheEntry(route, HttpRequestWrapper.wrap(req2), context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, HttpRequestWrapper.wrap(req1), context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, HttpRequestWrapper.wrap(req2), context, mockExecAware, mockCacheEntry);
verifyMocks();
Assert.assertEquals(2, impl.getScheduledIdentifiers().size());
@@ -171,14 +172,14 @@ public class TestAsynchronousValidator {
.setAsynchronousWorkersMax(1)
.setAsynchronousWorkersCore(1)
.build();
- impl = new AsynchronousValidator(mockClient, config);
+ impl = new AsynchronousValidator(config);
EasyMock.expect(mockCacheEntry.hasVariants()).andReturn(false);
EasyMock.expect(mockClient.revalidateCacheEntry(
route, request, context, mockExecAware, mockCacheEntry)).andReturn(null);
replayMocks();
- impl.revalidateCacheEntry(route, request, context, mockExecAware, mockCacheEntry);
+ impl.revalidateCacheEntry(mockClient, route, request, context, mockExecAware, mockCacheEntry);
try {
// shut down backend executor and make sure all finishes properly, 1 second should be sufficient
@@ -194,6 +195,17 @@ public class TestAsynchronousValidator {
}
}
+ @Test
+ public void testExecutorShutdownOnClose() throws IOException {
+ impl = new AsynchronousValidator(mockExecutor);
+
+ mockExecutor.shutdown();
+
+ replayMocks();
+ impl.close();
+ verifyMocks();
+ }
+
public void replayMocks() {
EasyMock.replay(mockExecutor);
EasyMock.replay(mockClient);