summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@vespa.ai>2023-06-13 17:02:58 +0200
committerJon Bratseth <bratseth@vespa.ai>2023-06-13 17:02:58 +0200
commit9869ca2ad01e423d9b250f188e3152fb693d97d8 (patch)
treeccbec341929899415ed7808c5160b37b9a30acbb /container-search
parent3092b0045dfb7e701f8a2a4b7a359acc696d9fc3 (diff)
Use a bound queue for rendering tasks
If we add rendering tasks faster than we are able to complete them we may run out of memory, so bound the queue.
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java11
-rw-r--r--container-search/src/main/java/com/yahoo/search/searchchain/RenderingExecutorFactory.java39
2 files changed, 40 insertions, 10 deletions
diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
index 87880ce2445..dc044c77c94 100644
--- a/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
+++ b/container-search/src/main/java/com/yahoo/search/searchchain/ExecutionFactory.java
@@ -86,7 +86,7 @@ public class ExecutionFactory extends AbstractComponent {
this.schemaInfo = schemaInfo;
this.specialTokens = new SpecialTokenRegistry(specialTokens);
this.linguistics = linguistics;
- this.renderingExecutor = createRenderingExecutor();
+ this.renderingExecutor = new RenderingExecutorFactory().createExecutor();
this.rendererRegistry = new RendererRegistry(renderers.allComponents(), renderingExecutor);
this.executor = executor != null ? executor : Executors.newSingleThreadExecutor();
}
@@ -151,13 +151,4 @@ public class ExecutionFactory extends AbstractComponent {
null);
}
- private static ThreadPoolExecutor createRenderingExecutor() {
- int threadCount = Runtime.getRuntime().availableProcessors();
- ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 1L, TimeUnit.SECONDS,
- new LinkedBlockingQueue<>(),
- ThreadFactoryFactory.getThreadFactory("common-rendering"));
- executor.prestartAllCoreThreads();
- return executor;
- }
-
}
diff --git a/container-search/src/main/java/com/yahoo/search/searchchain/RenderingExecutorFactory.java b/container-search/src/main/java/com/yahoo/search/searchchain/RenderingExecutorFactory.java
new file mode 100644
index 00000000000..f67db059470
--- /dev/null
+++ b/container-search/src/main/java/com/yahoo/search/searchchain/RenderingExecutorFactory.java
@@ -0,0 +1,39 @@
+package com.yahoo.search.searchchain;
+
+import com.yahoo.concurrent.ThreadFactoryFactory;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Factory of the executor passed to renderers by default.
+ *
+ * @author bratseth
+ */
+class RenderingExecutorFactory {
+
+ private final int maxQueuedRenderingTasksPerProcessor;
+ private final int availableProcessors;
+
+ public RenderingExecutorFactory() {
+ this.maxQueuedRenderingTasksPerProcessor = 100;
+ this.availableProcessors = Runtime.getRuntime().availableProcessors();
+ }
+
+ ThreadPoolExecutor createExecutor() {
+ int maxOutstandingTasks = maxQueuedRenderingTasksPerProcessor * availableProcessors;
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(availableProcessors, availableProcessors, 1L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(maxOutstandingTasks),
+ ThreadFactoryFactory.getThreadFactory("common-rendering"),
+ (task, exec) -> renderingRejected(maxOutstandingTasks));
+ executor.prestartAllCoreThreads();
+ return executor;
+ }
+
+ private void renderingRejected(int maxOutstandingTasks) {
+ throw new RejectedExecutionException("More than " + maxOutstandingTasks + " rendering tasks queued, rejecting this");
+ }
+
+}