Use a reasonable set of spawn strategies by default.
This is only enabled when using --incompatible_list_based_execution_strategy_selection.
Note that this does *not* yet disable the built-in fallback behavior in the spawn strategies, but that's not required for this feature to work. That'll just be a nice addition to make the code clearer and allows us to remove the fallback code from all strategies.
RELNOTES: When using --incompatible_list_based_execution_strategy_selection, Bazel will use remote execution by default (if you specify --remote_executor), otherwise persistent workers (if the action supports it), otherwise sandboxed local execution (if the action and platform supports it) and at last unsandboxed local execution. The flags --spawn_strategy and --strategy continue to work as before - this only sets new defaults for the case where you don't specify these flags.
PiperOrigin-RevId: 235932751
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD
index b36522d..f4d88c0 100644
--- a/src/main/java/com/google/devtools/build/lib/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/BUILD
@@ -749,6 +749,7 @@
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/concurrent",
+ "//src/main/java/com/google/devtools/build/lib/remote",
"//src/main/java/com/google/devtools/build/lib/rules/apple",
"//src/main/java/com/google/devtools/build/lib/rules/apple/cpp",
"//src/main/java/com/google/devtools/build/lib/rules/apple/swift",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelStrategyModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelStrategyModule.java
index 6b3712c..90cc493 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelStrategyModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelStrategyModule.java
@@ -21,6 +21,8 @@
import com.google.devtools.build.lib.exec.ExecutionOptions;
import com.google.devtools.build.lib.exec.ExecutorBuilder;
import com.google.devtools.build.lib.exec.SpawnCache;
+import com.google.devtools.build.lib.remote.RemoteModule;
+import com.google.devtools.build.lib.remote.RemoteOptions;
import com.google.devtools.build.lib.rules.android.WriteAdbArgsActionContext;
import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext;
import com.google.devtools.build.lib.rules.cpp.CppIncludeExtractionContext;
@@ -28,8 +30,10 @@
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
+import com.google.devtools.build.lib.util.OS;
import com.google.devtools.build.lib.util.RegexFilter;
import com.google.devtools.common.options.OptionsBase;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -38,7 +42,7 @@
@Override
public Iterable<Class<? extends OptionsBase>> getCommandOptions(Command command) {
return "build".equals(command.name())
- ? ImmutableList.of(ExecutionOptions.class)
+ ? ImmutableList.of(ExecutionOptions.class, RemoteOptions.class)
: ImmutableList.of();
}
@@ -46,11 +50,36 @@
public void executorInit(CommandEnvironment env, BuildRequest request, ExecutorBuilder builder) {
builder.addActionContext(new WriteAdbArgsActionContext(env.getClientEnv().get("HOME")));
ExecutionOptions options = env.getOptions().getOptions(ExecutionOptions.class);
+ RemoteOptions remoteOptions = env.getOptions().getOptions(RemoteOptions.class);
- // Default strategies for certain mnemonics - they can be overridden by --strategy= flags.
- builder.addStrategyByMnemonic("Javac", ImmutableList.of("worker"));
- builder.addStrategyByMnemonic("Closure", ImmutableList.of("worker"));
- builder.addStrategyByMnemonic("DexBuilder", ImmutableList.of("worker"));
+ List<String> spawnStrategies = new ArrayList<>(options.spawnStrategy);
+
+ if (options.incompatibleListBasedExecutionStrategySelection) {
+ if (spawnStrategies.isEmpty()) {
+ if (RemoteModule.shouldEnableRemoteExecution(remoteOptions)) {
+ spawnStrategies.add("remote");
+ }
+ spawnStrategies.add("worker");
+ // Sandboxing is not yet available on Windows.
+ if (OS.getCurrent() != OS.WINDOWS) {
+ spawnStrategies.add("sandboxed");
+ }
+ spawnStrategies.add("local");
+ }
+ } else {
+ // Default strategies for certain mnemonics - they can be overridden by --strategy= flags.
+ builder.addStrategyByMnemonic("Javac", ImmutableList.of("worker"));
+ builder.addStrategyByMnemonic("Closure", ImmutableList.of("worker"));
+ builder.addStrategyByMnemonic("DexBuilder", ImmutableList.of("worker"));
+
+ // The --spawn_strategy= flag is a bit special: If it's set to the empty string, we actually
+ // have to pass a literal empty string to the builder to trigger the "use the strategy that
+ // was registered last" behavior. Otherwise we would have no default strategy at all and Bazel
+ // would crash.
+ if (spawnStrategies.isEmpty()) {
+ spawnStrategies = ImmutableList.of("");
+ }
+ }
// Allow genrule_strategy to also be overridden by --strategy= flags.
builder.addStrategyByMnemonic("Genrule", options.genruleStrategy);
@@ -59,12 +88,6 @@
builder.addStrategyByMnemonic(strategy.getKey(), strategy.getValue());
}
- // The --spawn_strategy= flag is a bit special: If it's set to the empty string, we actually
- // have to pass a literal empty string to the builder to trigger the "use the strategy that was
- // registered last" behavior. Otherwise we would have no default strategy at all and Bazel would
- // crash.
- List<String> spawnStrategies =
- options.spawnStrategy.isEmpty() ? ImmutableList.of("") : options.spawnStrategy;
builder.addStrategyByMnemonic("", spawnStrategies);
for (Map.Entry<RegexFilter, List<String>> entry : options.strategyByRegexp) {
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteModule.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteModule.java
index 97926fc..25e23e4 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteModule.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteModule.java
@@ -110,6 +110,11 @@
return true; // if *all* > 0 violations have type MISSING
};
+ /** Returns whether remote execution should be available. */
+ public static boolean shouldEnableRemoteExecution(RemoteOptions options) {
+ return !Strings.isNullOrEmpty(options.remoteExecutor);
+ }
+
@Override
public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
RemoteOptions remoteOptions = env.getOptions().getOptions(RemoteOptions.class);
@@ -130,7 +135,7 @@
}
boolean enableBlobStoreCache = enableRestCache || enableDiskCache;
boolean enableGrpcCache = GrpcRemoteCache.isRemoteCacheOptions(remoteOptions);
- boolean enableRemoteExecution = !Strings.isNullOrEmpty(remoteOptions.remoteExecutor);
+ boolean enableRemoteExecution = shouldEnableRemoteExecution(remoteOptions);
if (enableBlobStoreCache && enableRemoteExecution) {
throw new AbruptExitException(
"Cannot combine gRPC based remote execution with local disk or HTTP-based caching",