summaryrefslogtreecommitdiffstats
path: root/container-core
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-30 12:24:15 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-30 12:24:15 +0200
commitb8bac3b2ba562d9d3a2faf13068d36cbaf9942f5 (patch)
treef61a751894bd48b30e25de036f5ef21e86e36d9e /container-core
parentd654f0ab3e25be8a85d596a5af13b430386baa9c (diff)
Don't reused renderer executors across renderer recycling
Diffstat (limited to 'container-core')
-rw-r--r--container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java5
-rw-r--r--container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java20
2 files changed, 24 insertions, 1 deletions
diff --git a/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java b/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java
index 6ebb328fafc..cc186ea21ee 100644
--- a/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java
+++ b/container-core/src/main/java/com/yahoo/processing/rendering/AsynchronousSectionedRenderer.java
@@ -112,7 +112,8 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e
// Rendering threads should never block.
// Burst traffic may add work faster than we can complete it, so use an unbounded queue.
- private static final ThreadPoolExecutor renderingExecutor = createExecutor();
+ // The executor SHOULD be reused across all instances having the same prototype
+ private final ThreadPoolExecutor renderingExecutor = createExecutor();
private static ThreadPoolExecutor createExecutor() {
int threadCount = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 1L, TimeUnit.SECONDS,
@@ -222,6 +223,8 @@ public abstract class AsynchronousSectionedRenderer<RESPONSE extends Response> e
Executor getExecutor() {
return beforeHandoverMode ? MoreExecutors.sameThreadExecutor() : renderingExecutor;
}
+ /** For inspection only; use getExecutor() for execution */
+ Executor getRenderingExecutor() { return renderingExecutor; }
/** The outermost execution which was run to create the response to render. */
public Execution getExecution() { return execution; }
diff --git a/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java b/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java
index b8efd8562b1..ab684872ce8 100644
--- a/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java
+++ b/container-core/src/test/java/com/yahoo/processing/rendering/AsynchronousSectionedRendererTest.java
@@ -36,6 +36,26 @@ public class AsynchronousSectionedRendererTest {
private static final Charset CHARSET = Utf8.getCharset();
@Test
+ public void testRenderersOfTheSamePrototypeUseTheSameExecutor() {
+ TestRenderer rendererPrototype = new TestRenderer();
+ TestRenderer rendererCopy1 = (TestRenderer)rendererPrototype.clone();
+ rendererCopy1.init();
+ assertTrue(rendererPrototype.getRenderingExecutor() == rendererCopy1.getRenderingExecutor());
+ }
+
+ @Test
+ public void testRenderersOfDifferentPrototypesUseDifferentExecutors() {
+ TestRenderer rendererPrototype1 = new TestRenderer();
+ TestRenderer rendererCopy1 = (TestRenderer)rendererPrototype1.clone();
+ rendererCopy1.init();
+
+ TestRenderer rendererPrototype2 = new TestRenderer();
+ TestRenderer rendererCopy2 = (TestRenderer)rendererPrototype2.clone();
+ rendererCopy2.init();
+ assertTrue(rendererPrototype1.getRenderingExecutor() != rendererCopy2.getRenderingExecutor());
+ }
+
+ @Test
public void testAsyncSectionedRenderer() throws IOException, InterruptedException {
StringDataList dataList = createDataListWithStrangeStrings();