Make the number of jobs in the worker configurable via an option
PiperOrigin-RevId: 161505952
diff --git a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/BUILD b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/BUILD
index 7e85b24..60d4433 100644
--- a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/BUILD
+++ b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/BUILD
@@ -25,6 +25,7 @@
"//src/main/java/com/google/devtools/build/lib:unix",
"//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib:vfs",
+ "//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/remote",
"//src/main/java/com/google/devtools/common/options",
"//src/main/protobuf:option_filters_java_proto",
diff --git a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/ExecutionServer.java b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/ExecutionServer.java
index 034ff9d..ec8dc95 100644
--- a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/ExecutionServer.java
+++ b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/ExecutionServer.java
@@ -85,9 +85,7 @@
private final RemoteWorkerOptions workerOptions;
private final SimpleBlobStoreActionCache cache;
private final ConcurrentHashMap<String, ListenableFuture<ActionResult>> operationsCache;
- private final ListeningExecutorService executorService =
- MoreExecutors.listeningDecorator(
- new ThreadPoolExecutor(0, 8, 1000, TimeUnit.SECONDS, new LinkedBlockingQueue<>()));
+ private final ListeningExecutorService executorService;
public ExecutionServer(
Path workPath,
@@ -100,6 +98,13 @@
this.workerOptions = workerOptions;
this.cache = cache;
this.operationsCache = operationsCache;
+ this.executorService =
+ MoreExecutors.listeningDecorator(
+ new ThreadPoolExecutor(
+ 1, workerOptions.jobs, // always have one thread available, and use at most jobs
+ 1000, TimeUnit.SECONDS, // shut down idle threads after 1000 seconds
+ // TODO(ulfjack): We need to reject work eventually.
+ new LinkedBlockingQueue<>())); // no blocking, we can always take more
}
@Override
diff --git a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/RemoteWorkerOptions.java b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/RemoteWorkerOptions.java
index e8bc12a..b66e07b 100644
--- a/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/RemoteWorkerOptions.java
+++ b/src/tools/remote_worker/src/main/java/com/google/devtools/build/remote/RemoteWorkerOptions.java
@@ -14,9 +14,12 @@
package com.google.devtools.build.remote;
+import com.google.devtools.build.lib.actions.LocalHostCapacity;
+import com.google.devtools.common.options.Converters.RangeConverter;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionDocumentationCategory;
import com.google.devtools.common.options.OptionsBase;
+import com.google.devtools.common.options.OptionsParsingException;
import com.google.devtools.common.options.proto.OptionFilters.OptionEffectTag;
import java.util.List;
@@ -116,4 +119,42 @@
help = "When using sandboxing, block network access for running actions."
)
public boolean sandboxingBlockNetwork;
+
+ @Option(
+ name = "jobs",
+ defaultValue = "auto",
+ converter = JobsConverter.class,
+ category = "build_worker",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ help =
+ "The maximum number of concurrent jobs to run. \"auto\" means to use a reasonable value"
+ + " derived from the machine's hardware profile (e.g. the number of processors)."
+ + " Values above " + MAX_JOBS + " are not allowed."
+ )
+ public int jobs;
+
+ private static final int MAX_JOBS = 16384;
+
+ /** Converter for jobs: [0, MAX_JOBS] or "auto". */
+ public static class JobsConverter extends RangeConverter {
+ public JobsConverter() {
+ super(0, MAX_JOBS);
+ }
+
+ @Override
+ public Integer convert(String input) throws OptionsParsingException {
+ if (input.equals("auto")) {
+ int autoJobs = (int) Math.ceil(LocalHostCapacity.getLocalHostCapacity().getCpuUsage());
+ return Math.min(autoJobs, MAX_JOBS);
+ } else {
+ return super.convert(input);
+ }
+ }
+
+ @Override
+ public String getTypeDescription() {
+ return "\"auto\" or " + super.getTypeDescription();
+ }
+ }
}