Delete SpawnActionContextMaps.
Part of the rollforward of https://github.com/bazelbuild/bazel/commit/37aeabcd39fe326d1c4e55693d8d207f9f7ac6c4.
PiperOrigin-RevId: 315517851
diff --git a/src/main/java/com/google/devtools/build/lib/exec/BUILD b/src/main/java/com/google/devtools/build/lib/exec/BUILD
index c90923a..491df37 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/exec/BUILD
@@ -107,9 +107,7 @@
srcs = ["ExecutorBuilder.java"],
deps = [
":executor_lifecycle_listener",
- ":spawn_action_context_maps",
"//src/main/java/com/google/devtools/build/lib/actions",
- "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
"//third_party:guava",
],
)
@@ -201,27 +199,6 @@
)
java_library(
- name = "spawn_action_context_maps",
- srcs = [
- "ProxySpawnActionContext.java",
- "SpawnActionContextMaps.java",
- ],
- deps = [
- ":abstract_spawn_strategy",
- ":remote_local_fallback_registry",
- "//src/main/java/com/google/devtools/build/lib/actions",
- "//src/main/java/com/google/devtools/build/lib/events",
- "//src/main/java/com/google/devtools/build/lib/util",
- "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
- "//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code",
- "//src/main/protobuf:failure_details_java_proto",
- "//third_party:auto_value",
- "//third_party:guava",
- "//third_party:jsr305",
- ],
-)
-
-java_library(
name = "spawn_cache",
srcs = ["SpawnCache.java"],
deps = [
diff --git a/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java b/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
index 3c40288..78da325 100644
--- a/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/exec/ExecutorBuilder.java
@@ -16,7 +16,6 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
-import com.google.devtools.build.lib.util.AbruptExitException;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -25,15 +24,9 @@
* class is part of the module API, which allows modules to affect how the executor is initialized.
*/
public class ExecutorBuilder {
- private final SpawnActionContextMaps.Builder spawnActionContextMapsBuilder =
- new SpawnActionContextMaps.Builder();
private final Set<ExecutorLifecycleListener> executorLifecycleListeners = new LinkedHashSet<>();
private ActionInputPrefetcher prefetcher;
- public SpawnActionContextMaps getSpawnActionContextMaps() throws AbruptExitException {
- return spawnActionContextMapsBuilder.build();
- }
-
/** Returns all executor lifecycle listeners registered with this builder so far. */
public ImmutableSet<ExecutorLifecycleListener> getExecutorLifecycleListeners() {
return ImmutableSet.copyOf(executorLifecycleListeners);
diff --git a/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java b/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java
deleted file mode 100644
index ae0960a..0000000
--- a/src/main/java/com/google/devtools/build/lib/exec/ProxySpawnActionContext.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.exec;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionContext;
-import com.google.devtools.build.lib.actions.ExecException;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnContinuation;
-import com.google.devtools.build.lib.actions.SpawnResult;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.actions.UserExecException;
-import com.google.devtools.build.lib.events.NullEventHandler;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/** Proxy that looks up the right SpawnActionContext for a spawn during {@link #exec}. */
-public final class ProxySpawnActionContext implements SpawnStrategy {
-
- private final SpawnActionContextMaps spawnActionContextMaps;
-
- /**
- * Creates a new {@link ProxySpawnActionContext}.
- *
- * @param spawnActionContextMaps The {@link SpawnActionContextMaps} to use to decide which {@link
- * SpawnStrategy} should execute a given {@link Spawn} during {@link #exec}.
- */
- public ProxySpawnActionContext(SpawnActionContextMaps spawnActionContextMaps) {
- this.spawnActionContextMaps = spawnActionContextMaps;
- }
-
- @Override
- public ImmutableList<SpawnResult> exec(Spawn spawn, ActionExecutionContext actionExecutionContext)
- throws ExecException, InterruptedException {
- return resolveOne(spawn, actionExecutionContext).exec(spawn, actionExecutionContext);
- }
-
- @Override
- public SpawnContinuation beginExecution(
- Spawn spawn, ActionExecutionContext actionExecutionContext) throws InterruptedException {
- SpawnStrategy resolvedStrategy;
- try {
- resolvedStrategy = resolveOne(spawn, actionExecutionContext);
- } catch (ExecException e) {
- return SpawnContinuation.failedWithExecException(e);
- }
- return resolvedStrategy.beginExecution(spawn, actionExecutionContext);
- }
-
- private SpawnStrategy resolveOne(Spawn spawn, ActionExecutionContext actionExecutionContext)
- throws UserExecException {
- List<SpawnStrategy> strategies = resolve(spawn, actionExecutionContext);
-
- // Because the strategies are ordered by preference, we can execute the spawn with the best
- // possible one by simply filtering out the ones that can't execute it and then picking the
- // first one from the remaining strategies in the list.
- return strategies.get(0);
- }
-
- /**
- * Returns the list of {@link SpawnStrategy}s that should be used to execute the given spawn.
- *
- * @param spawn The spawn for which the correct {@link SpawnStrategy} should be determined.
- * @param eventHandler An event handler that can be used to print messages while resolving the
- * correct {@link SpawnStrategy} for the given spawn.
- */
- @VisibleForTesting
- public List<SpawnStrategy> resolve(Spawn spawn, ActionExecutionContext actionExecutionContext)
- throws UserExecException {
- List<SpawnStrategy> strategies =
- spawnActionContextMaps.getSpawnActionContexts(
- spawn, actionExecutionContext.getEventHandler());
-
- strategies =
- strategies.stream()
- .filter(spawnActionContext -> spawnActionContext.canExec(spawn, actionExecutionContext))
- .collect(Collectors.toList());
-
- if (strategies.isEmpty()) {
- throw new UserExecException(
- String.format(
- "No usable spawn strategy found for spawn with mnemonic %s. Your"
- + " --spawn_strategy, --genrule_strategy or --strategy flags are probably too"
- + " strict. Visit https://github.com/bazelbuild/bazel/issues/7480 for"
- + " migration advice",
- spawn.getMnemonic()));
- }
-
- return strategies;
- }
-
- @Override
- public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
- return spawnActionContextMaps.getSpawnActionContexts(spawn, NullEventHandler.INSTANCE).stream()
- .anyMatch(spawnActionContext -> spawnActionContext.canExec(spawn, actionContextRegistry));
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java b/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java
deleted file mode 100644
index b8aae55..0000000
--- a/src/main/java/com/google/devtools/build/lib/exec/SpawnActionContextMaps.java
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2018 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.exec;
-
-import com.google.auto.value.AutoValue;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableClassToInstanceMap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableListMultimap;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Table;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionContextMarker;
-import com.google.devtools.build.lib.actions.DynamicStrategyRegistry;
-import com.google.devtools.build.lib.actions.SandboxedSpawnStrategy;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.events.EventHandler;
-import com.google.devtools.build.lib.events.Reporter;
-import com.google.devtools.build.lib.server.FailureDetails;
-import com.google.devtools.build.lib.server.FailureDetails.ExecutionOptions.Code;
-import com.google.devtools.build.lib.server.FailureDetails.FailureDetail;
-import com.google.devtools.build.lib.util.AbruptExitException;
-import com.google.devtools.build.lib.util.DetailedExitCode;
-import com.google.devtools.build.lib.util.RegexFilter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-
-/**
- * Container for looking up the {@link ActionContext} to use for a given action.
- *
- * <p>Holds {@link ActionContext} mappings populated by modules. These include mappings from
- * mnemonics and from description patterns.
- *
- * <p>At startup time, the application provides {@link Builder} to each module to register its
- * contexts and mappings. At runtime, the {@link BlazeExecutor} uses the constructed object to find
- * the context for each action.
- */
-public final class SpawnActionContextMaps
- implements DynamicStrategyRegistry,
- RemoteLocalFallbackRegistry,
- ActionContext.ActionContextRegistry {
-
- /** A stored entry for a {@link RegexFilter} to {@link SpawnStrategy} mapping. */
- @AutoValue
- public abstract static class RegexFilterSpawnStrategy {
- public abstract RegexFilter regexFilter();
-
- public abstract ImmutableList<SpawnStrategy> strategies();
- }
-
- private final ImmutableSortedMap<String, List<SpawnStrategy>> mnemonicToSpawnStrategiesMap;
- private final ImmutableClassToInstanceMap<ActionContext> strategies;
- private final ImmutableList<RegexFilterSpawnStrategy> spawnStrategyRegexList;
- private final ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToRemoteDynamicStrategies;
- private final ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToLocalDynamicStrategies;
- private final ImmutableMap<Class<? extends ActionContext>, ActionContext> contextMap;
- @Nullable private final AbstractSpawnStrategy remoteLocalFallbackStrategy;
-
- private SpawnActionContextMaps(
- ImmutableSortedMap<String, List<SpawnStrategy>> mnemonicToSpawnStrategiesMap,
- ImmutableClassToInstanceMap<ActionContext> strategies,
- ImmutableList<RegexFilterSpawnStrategy> spawnStrategyRegexList,
- ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToRemoteDynamicStrategies,
- ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToLocalDynamicStrategies,
- AbstractSpawnStrategy remoteLocalFallbackStrategy) {
- this.mnemonicToSpawnStrategiesMap = mnemonicToSpawnStrategiesMap;
- this.strategies = strategies;
- this.spawnStrategyRegexList = spawnStrategyRegexList;
- this.mnemonicToRemoteDynamicStrategies = mnemonicToRemoteDynamicStrategies;
- this.mnemonicToLocalDynamicStrategies = mnemonicToLocalDynamicStrategies;
- this.remoteLocalFallbackStrategy = remoteLocalFallbackStrategy;
- contextMap = createContextMap();
- }
-
- /**
- * Returns a list of appropriate {@link ActionContext}s to execute the given {@link Spawn} with.
- *
- * <p>If the reason for selecting the context is worth mentioning to the user, logs a message
- * using the given {@link Reporter}.
- */
- List<SpawnStrategy> getSpawnActionContexts(Spawn spawn, EventHandler reporter) {
- Preconditions.checkNotNull(spawn);
- if (!spawnStrategyRegexList.isEmpty() && spawn.getResourceOwner() != null
- // Don't override test strategies by --strategy_regexp for backwards compatibility.
- && !"TestRunner".equals(spawn.getMnemonic())) {
- String description = spawn.getResourceOwner().getProgressMessage();
- if (description != null) {
- for (RegexFilterSpawnStrategy entry : spawnStrategyRegexList) {
- if (entry.regexFilter().isIncluded(description) && entry.strategies() != null) {
- reporter.handle(
- Event.progress(description + " with context " + entry.strategies().toString()));
- return entry.strategies();
- }
- }
- }
- }
- List<SpawnStrategy> strategies = mnemonicToSpawnStrategiesMap.get(spawn.getMnemonic());
- if (strategies != null) {
- return strategies;
- }
- return Preconditions.checkNotNull(mnemonicToSpawnStrategiesMap.get(""));
- }
-
- @Override
- public List<SandboxedSpawnStrategy> getDynamicSpawnActionContexts(
- Spawn spawn, DynamicMode dynamicMode) {
- ImmutableMultimap<String, SandboxedSpawnStrategy> mnemonicToDynamicStrategies =
- dynamicMode == DynamicStrategyRegistry.DynamicMode.REMOTE
- ? mnemonicToRemoteDynamicStrategies
- : mnemonicToLocalDynamicStrategies;
- return ImmutableList.<SandboxedSpawnStrategy>builder()
- .addAll(mnemonicToDynamicStrategies.get(spawn.getMnemonic()))
- .addAll(mnemonicToDynamicStrategies.get(""))
- .build();
- }
-
- @Nullable
- @Override
- public AbstractSpawnStrategy getRemoteLocalFallbackStrategy() {
- return remoteLocalFallbackStrategy;
- }
-
- private ImmutableMap<Class<? extends ActionContext>, ActionContext> createContextMap() {
- Map<Class<? extends ActionContext>, ActionContext> contextMap = new HashMap<>();
- for (Map.Entry<Class<? extends ActionContext>, ActionContext> typeToStrategy :
- strategies.entrySet()) {
- ActionContext strategy = typeToStrategy.getValue();
- contextMap.put(typeToStrategy.getKey(), strategy);
- contextMap.put(strategy.getClass(), strategy);
- }
- contextMap.put(SpawnStrategy.class, new ProxySpawnActionContext(this));
- contextMap.put(DynamicStrategyRegistry.class, this);
- contextMap.put(RemoteLocalFallbackRegistry.class, this);
- return ImmutableMap.copyOf(contextMap);
- }
-
- @Nullable
- @Override
- public <T extends ActionContext> T getContext(Class<T> identifyingType) {
- return identifyingType.cast(contextMap.get(identifyingType));
- }
-
- /** Returns a list of all referenced {@link ActionContext} instances. */
- @VisibleForTesting
- public ImmutableList<ActionContext> allContexts() {
- // We need to keep only the last occurrences of the entries in contextImplementations
- // (so we respect insertion order but also instantiate them only once).
- LinkedHashSet<ActionContext> allContexts = new LinkedHashSet<>(strategies.values());
- mnemonicToSpawnStrategiesMap.values().forEach(allContexts::addAll);
- spawnStrategyRegexList.forEach(x -> allContexts.addAll(x.strategies()));
- return ImmutableList.copyOf(allContexts);
- }
-
- /**
- * Notifies all (non-dynamic) contexts stored in this context map that they are {@link
- * ActionContext#usedContext used}.
- */
- public void notifyUsed() {
- for (ActionContext context : allContexts()) {
- context.usedContext(this);
- }
- }
-
- @Override
- public void notifyUsedDynamic(ActionContext.ActionContextRegistry actionContextRegistry) {
- for (SandboxedSpawnStrategy context : mnemonicToRemoteDynamicStrategies.values()) {
- context.usedContext(actionContextRegistry);
- }
-
- for (SandboxedSpawnStrategy context : mnemonicToLocalDynamicStrategies.values()) {
- context.usedContext(actionContextRegistry);
- }
- }
-
- /**
- * Print a sorted list of our (Spawn)ActionContext maps.
- *
- * <p>Prints out debug information about the mappings.
- */
- void debugPrintSpawnActionContextMaps(Reporter reporter) {
- for (Entry<String, List<SpawnStrategy>> entry : mnemonicToSpawnStrategiesMap.entrySet()) {
- List<String> strategyNames =
- entry.getValue().stream()
- .map(spawnActionContext -> spawnActionContext.getClass().getSimpleName())
- .collect(Collectors.toList());
- reporter.handle(
- Event.info(
- String.format(
- "SpawnActionContextMap: \"%s\" = [%s]",
- entry.getKey(), Joiner.on(", ").join(strategyNames))));
- }
-
- ImmutableMap<Class<? extends ActionContext>, ActionContext> contextMap = createContextMap();
- TreeMap<String, String> sortedContextMapWithSimpleNames = new TreeMap<>();
- for (Map.Entry<Class<? extends ActionContext>, ActionContext> entry : contextMap.entrySet()) {
- sortedContextMapWithSimpleNames.put(
- entry.getKey().getSimpleName(), entry.getValue().getClass().getSimpleName());
- }
- for (Map.Entry<String, String> entry : sortedContextMapWithSimpleNames.entrySet()) {
- // Skip uninteresting identity mappings of contexts.
- if (!entry.getKey().equals(entry.getValue())) {
- reporter.handle(
- Event.info(String.format("ContextMap: %s = %s", entry.getKey(), entry.getValue())));
- }
- }
-
- for (RegexFilterSpawnStrategy entry : spawnStrategyRegexList) {
- reporter.handle(
- Event.info(
- String.format(
- "SpawnActionContextMap: \"%s\" = %s",
- entry.regexFilter().toString(), entry.strategies().getClass().getSimpleName())));
- }
- }
-
- @VisibleForTesting
- public static SpawnActionContextMaps createStub(
- Map<Class<? extends ActionContext>, ActionContext> strategies,
- Map<String, List<SpawnStrategy>> spawnStrategyMnemonicMap) {
- return new SpawnActionContextMaps(
- ImmutableSortedMap.copyOf(spawnStrategyMnemonicMap, String.CASE_INSENSITIVE_ORDER),
- ImmutableClassToInstanceMap.copyOf(strategies),
- ImmutableList.of(),
- ImmutableMultimap.of(),
- ImmutableMultimap.of(),
- /* remoteLocalFallbackStrategy=*/ null);
- }
-
- /** A stored entry for a {@link RegexFilter} to {@code strategy} mapping. */
- @AutoValue
- public abstract static class RegexFilterStrategy {
- public abstract RegexFilter regexFilter();
-
- public abstract ImmutableList<String> strategy();
- }
-
- /** Builder for {@code SpawnActionContextMaps}. */
- public static final class Builder {
- private final LinkedHashMultimap<String, String> strategyByMnemonicMap =
- LinkedHashMultimap.create();
- private ImmutableListMultimap.Builder<Class<? extends ActionContext>, String>
- strategyByContextMapBuilder = ImmutableListMultimap.builder();
- private final ImmutableList.Builder<RegexFilterStrategy> strategyByRegexpBuilder =
- ImmutableList.builder();
- private final LinkedHashMultimap<String, String> remoteDynamicStrategyByMnemonicMap =
- LinkedHashMultimap.create();
- private final LinkedHashMultimap<String, String> localDynamicStrategyByMnemonicMap =
- LinkedHashMultimap.create();
- private final List<ActionContextInformation<?>> actionContexts = new ArrayList<>();
- @Nullable private String remoteLocalFallbackStrategyName;
-
- /**
- * Returns a builder modules can use to add mappings from mnemonics to strategy names.
- *
- * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
- * the map at all, the choice of the implementation is left to Blaze.
- *
- * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
- * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
- * last one added.
- */
- public LinkedHashMultimap<String, String> strategyByMnemonicMap() {
- return strategyByMnemonicMap;
- }
-
- /**
- * Returns a builder modules can use to add mappings from mnemonics to strategy names for use in
- * the remote branch of dynamic execution.
- *
- * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
- * the map at all, the choice of the implementation is left to Blaze.
- *
- * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
- * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
- * last one added.
- */
- public LinkedHashMultimap<String, String> remoteDynamicStrategyByMnemonicMap() {
- return remoteDynamicStrategyByMnemonicMap;
- }
-
- /**
- * Returns a builder modules can use to add mappings from mnemonics to strategy names for use in
- * the local branch of dynamic execution.
- *
- * <p>If a spawn action is executed whose mnemonic maps to the empty string or is not present in
- * the map at all, the choice of the implementation is left to Blaze.
- *
- * <p>Matching on mnemonics is done case-insensitively so it is recommended that any module
- * makes sure that no two strategies refer to the same mnemonic. If they do, Blaze will pick the
- * last one added.
- */
- public LinkedHashMultimap<String, String> localDynamicStrategyByMnemonicMap() {
- return localDynamicStrategyByMnemonicMap;
- }
-
- /**
- * Sets the command-line identifier of the strategy to be used when falling back from remote to
- * local execution.
- *
- * <p>Note that this is an optional setting, if not provided {@link
- * SpawnActionContextMaps#getRemoteLocalFallbackStrategy()} will return {@code null}. If the
- * value <b>is</b> provided it must match the commandline identifier of a registered strategy
- * (at {@linkplain #build build} time).
- */
- public void setRemoteFallbackStrategy(String remoteLocalFallbackStrategy) {
- this.remoteLocalFallbackStrategyName = remoteLocalFallbackStrategy;
- }
-
- /**
- * Returns a builder modules can use to associate {@link ActionContext} classes with strategy
- * names.
- */
- public ImmutableMultimap.Builder<Class<? extends ActionContext>, String>
- strategyByContextMap() {
- return strategyByContextMapBuilder;
- }
-
- /** Adds a mapping from the given {@link RegexFilter} to a {@code strategy}. */
- public void addStrategyByRegexp(RegexFilter regexFilter, List<String> strategy) {
- strategyByRegexpBuilder.add(
- new AutoValue_SpawnActionContextMaps_RegexFilterStrategy(
- regexFilter, ImmutableList.copyOf(strategy)));
- }
-
- /**
- * Adds a context implementation to this map with the given identifying type and command-line
- * identifiers.
- *
- * <p>If two contexts are added for the same identifying type and they are not distinguished by
- * a restriction to a different command-line identifier then the last registered implementation
- * is used.
- */
- public <T extends ActionContext> Builder addContext(
- Class<T> identifyingType, T context, String... commandLineIdentifiers) {
- actionContexts.add(
- new AutoValue_SpawnActionContextMaps_ActionContextInformation<>(
- context, identifyingType, ImmutableList.copyOf(commandLineIdentifiers)));
- return this;
- }
-
- /** Builds a {@link SpawnActionContextMaps} instance. */
- public SpawnActionContextMaps build() throws AbruptExitException {
- StrategyConverter strategyConverter = new StrategyConverter(actionContexts);
-
- ImmutableSortedMap.Builder<String, List<SpawnStrategy>> spawnStrategyMap =
- ImmutableSortedMap.orderedBy(String.CASE_INSENSITIVE_ORDER);
- HashMap<Class<? extends ActionContext>, ActionContext> strategies = new HashMap<>();
- ImmutableList.Builder<RegexFilterSpawnStrategy> spawnStrategyRegexList =
- ImmutableList.builder();
-
- for (String mnemonic : strategyByMnemonicMap.keySet()) {
- ImmutableList.Builder<SpawnStrategy> spawnStrategies = ImmutableList.builder();
- Set<String> strategiesForMnemonic = strategyByMnemonicMap.get(mnemonic);
- for (String strategy : strategiesForMnemonic) {
- SpawnStrategy spawnStrategy =
- strategyConverter.getStrategy(SpawnStrategy.class, strategy);
- if (spawnStrategy == null) {
- String strategyOrNull = Strings.emptyToNull(strategy);
- throw makeExceptionForInvalidStrategyValue(
- strategy,
- Joiner.on(' ').skipNulls().join(strategyOrNull, "spawn"),
- strategyConverter.getValidValues(SpawnStrategy.class));
- }
- spawnStrategies.add(spawnStrategy);
- }
- spawnStrategyMap.put(mnemonic, spawnStrategies.build());
- }
-
- Set<ActionContext> seenContext = new HashSet<>();
- for (Map.Entry<Class<? extends ActionContext>, String> entry :
- strategyByContextMapBuilder.orderValuesBy(Collections.reverseOrder()).build().entries()) {
- ActionContext context = strategyConverter.getStrategy(entry.getKey(), entry.getValue());
- if (context == null) {
- throw makeExceptionForInvalidStrategyValue(
- entry.getValue(),
- strategyConverter.getUserFriendlyName(entry.getKey()),
- strategyConverter.getValidValues(entry.getKey()));
- }
- if (seenContext.contains(context)) {
- continue;
- }
- seenContext.add(context);
- strategies.put(entry.getKey(), context);
- }
-
- for (RegexFilterStrategy entry : strategyByRegexpBuilder.build()) {
- ImmutableList.Builder<SpawnStrategy> spawnStrategies = ImmutableList.builder();
- List<String> strategiesForRegex = entry.strategy();
- for (String strategy : strategiesForRegex) {
- SpawnStrategy spawnStrategy =
- strategyConverter.getStrategy(SpawnStrategy.class, strategy);
- if (spawnStrategy == null) {
- strategy = Strings.emptyToNull(strategy);
- throw makeExceptionForInvalidStrategyValue(
- entry.regexFilter().toString(),
- Joiner.on(' ').skipNulls().join(strategy, "spawn"),
- strategyConverter.getValidValues(SpawnStrategy.class));
- }
- spawnStrategies.add(spawnStrategy);
- }
- spawnStrategyRegexList.add(
- new AutoValue_SpawnActionContextMaps_RegexFilterSpawnStrategy(
- entry.regexFilter(), spawnStrategies.build()));
- }
-
- AbstractSpawnStrategy remoteLocalFallbackStrategy = null;
- if (remoteLocalFallbackStrategyName != null) {
- SpawnStrategy strategy =
- strategyConverter.getStrategy(SpawnStrategy.class, remoteLocalFallbackStrategyName);
- if (!(strategy instanceof AbstractSpawnStrategy)) {
- throw makeExceptionForInvalidStrategyValue(
- remoteLocalFallbackStrategyName,
- "remote local fallback",
- strategyConverter.getValidValues(SpawnStrategy.class, "remote"));
- }
- remoteLocalFallbackStrategy = (AbstractSpawnStrategy) strategy;
- }
-
- return new SpawnActionContextMaps(
- spawnStrategyMap.build(),
- ImmutableClassToInstanceMap.copyOf(strategies),
- spawnStrategyRegexList.build(),
- toActionContexts(strategyConverter, remoteDynamicStrategyByMnemonicMap),
- toActionContexts(strategyConverter, localDynamicStrategyByMnemonicMap),
- remoteLocalFallbackStrategy);
- }
-
- private ImmutableMultimap<String, SandboxedSpawnStrategy> toActionContexts(
- StrategyConverter strategyConverter,
- LinkedHashMultimap<String, String> dynamicStrategyByMnemonicMap)
- throws AbruptExitException {
- ImmutableMultimap.Builder<String, SandboxedSpawnStrategy> mnemonicToStrategies =
- ImmutableMultimap.builder();
- for (Entry<String, Collection<String>> mnemonicToIdentifiers :
- dynamicStrategyByMnemonicMap.asMap().entrySet()) {
- for (String identifier : mnemonicToIdentifiers.getValue()) {
- if (identifier.isEmpty()) {
- continue;
- }
- SpawnStrategy strategy = strategyConverter.getStrategy(SpawnStrategy.class, identifier);
- if (strategy == null) {
- throw makeExceptionForInvalidStrategyValue(
- identifier,
- Joiner.on(' ').skipNulls().join(Strings.emptyToNull(identifier), "spawn"),
- strategyConverter.getValidValues(SpawnStrategy.class));
- }
- if (!(strategy instanceof SandboxedSpawnStrategy)) {
- throw createExitException(
- "Requested strategy " + identifier + " exists but does not support sandboxing",
- Code.REQUESTED_STRATEGY_INCOMPATIBLE_WITH_SANDBOXING);
- }
- mnemonicToStrategies.put(
- mnemonicToIdentifiers.getKey(), (SandboxedSpawnStrategy) strategy);
- }
- }
- return mnemonicToStrategies.build();
- }
- }
-
- private static AbruptExitException makeExceptionForInvalidStrategyValue(
- String value, String strategy, String validValues) {
- return createExitException(
- String.format(
- "'%s' is an invalid value for %s strategy. Valid values are: %s",
- value, strategy, validValues),
- Code.INVALID_STRATEGY);
- }
-
- private static AbruptExitException createExitException(String message, Code detailedCode) {
- return new AbruptExitException(
- DetailedExitCode.of(
- FailureDetail.newBuilder()
- .setMessage(message)
- .setExecutionOptions(
- FailureDetails.ExecutionOptions.newBuilder().setCode(detailedCode))
- .build()));
- }
-
- private static class StrategyConverter {
- private Table<Class<? extends ActionContext>, String, ActionContext> classMap =
- HashBasedTable.create();
- private Map<Class<? extends ActionContext>, ActionContext> defaultClassMap = new HashMap<>();
-
- /** Aggregates all {@link ActionContext}s that are in {@code contextProviders}. */
- private StrategyConverter(List<ActionContextInformation<?>> actionContexts) {
- for (ActionContextInformation<?> contextInformation : actionContexts) {
- defaultClassMap.put(contextInformation.identifyingType(), contextInformation.context());
-
- for (String name : contextInformation.commandLineIdentifiers()) {
- classMap.put(contextInformation.identifyingType(), name, contextInformation.context());
- }
- }
- }
-
- @SuppressWarnings("unchecked")
- private <T extends ActionContext> T getStrategy(Class<T> clazz, String name) {
- return (T) (name.isEmpty() ? defaultClassMap.get(clazz) : classMap.get(clazz, name));
- }
-
- private String getValidValues(Class<? extends ActionContext> context, String... excludes) {
- ImmutableSet<String> excludedNames = ImmutableSet.copyOf(excludes);
- return classMap.row(context).keySet().stream()
- .filter(s -> !excludedNames.contains(s))
- .sorted()
- .collect(Collectors.joining(", "));
- }
-
- private String getUserFriendlyName(Class<? extends ActionContext> context) {
- ActionContextMarker marker = context.getAnnotation(ActionContextMarker.class);
- return marker != null ? marker.name() : context.getSimpleName();
- }
- }
-
- @AutoValue
- abstract static class ActionContextInformation<T extends ActionContext> {
- abstract T context();
-
- abstract Class<T> identifyingType();
-
- abstract ImmutableList<String> commandLineIdentifiers();
- }
-}
diff --git a/src/test/java/com/google/devtools/build/lib/dynamic/BUILD b/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
index 6fcae49..3338aa1 100644
--- a/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
@@ -22,9 +22,7 @@
"//src/main/java/com/google/devtools/build/lib/dynamic",
"//src/main/java/com/google/devtools/build/lib/exec:blaze_executor",
"//src/main/java/com/google/devtools/build/lib/exec:execution_options",
- "//src/main/java/com/google/devtools/build/lib/exec:executor_builder",
"//src/main/java/com/google/devtools/build/lib/exec:module_action_context_registry",
- "//src/main/java/com/google/devtools/build/lib/exec:spawn_action_context_maps",
"//src/main/java/com/google/devtools/build/lib/exec:spawn_strategy_registry",
"//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception",
"//src/main/java/com/google/devtools/build/lib/util/io",
diff --git a/src/test/java/com/google/devtools/build/lib/exec/BUILD b/src/test/java/com/google/devtools/build/lib/exec/BUILD
index 89cef69..7817e8d 100644
--- a/src/test/java/com/google/devtools/build/lib/exec/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/exec/BUILD
@@ -38,7 +38,6 @@
"//src/main/java/com/google/devtools/build/lib/exec:execution_options",
"//src/main/java/com/google/devtools/build/lib/exec:module_action_context_registry",
"//src/main/java/com/google/devtools/build/lib/exec:single_build_file_cache",
- "//src/main/java/com/google/devtools/build/lib/exec:spawn_action_context_maps",
"//src/main/java/com/google/devtools/build/lib/exec:spawn_cache",
"//src/main/java/com/google/devtools/build/lib/exec:spawn_exec_exception",
"//src/main/java/com/google/devtools/build/lib/exec:spawn_input_expander",
diff --git a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java b/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
deleted file mode 100644
index 67856b1..0000000
--- a/src/test/java/com/google/devtools/build/lib/exec/SpawnActionContextMapsTest.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2018 The Bazel Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.exec;
-
-import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Mockito.when;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.eventbus.EventBus;
-import com.google.devtools.build.lib.actions.ActionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionContext;
-import com.google.devtools.build.lib.actions.ActionExecutionMetadata;
-import com.google.devtools.build.lib.actions.ExecException;
-import com.google.devtools.build.lib.actions.Spawn;
-import com.google.devtools.build.lib.actions.SpawnResult;
-import com.google.devtools.build.lib.actions.SpawnStrategy;
-import com.google.devtools.build.lib.events.Reporter;
-import com.google.devtools.build.lib.testutil.Suite;
-import com.google.devtools.build.lib.testutil.TestSpec;
-import com.google.devtools.build.lib.util.RegexFilter.RegexFilterConverter;
-import java.util.List;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.Mockito;
-
-/** Tests of {@link SpawnActionContextMaps}. */
-@RunWith(JUnit4.class)
-@TestSpec(size = Suite.SMALL_TESTS)
-public class SpawnActionContextMapsTest {
-
- private SpawnActionContextMaps.Builder builder;
- private final RegexFilterConverter converter = new RegexFilterConverter();
- private final EventBus bus = new EventBus();
- private final Reporter reporter = new Reporter(bus);
-
- private static final AC1 ac1 = new AC1();
- private static final AC2 ac2 = new AC2();
-
- @Before
- public void setUp() {
- builder =
- new SpawnActionContextMaps.Builder()
- .addContext(SpawnStrategy.class, ac1, "ac1")
- .addContext(SpawnStrategy.class, ac2, "ac2");
- }
-
- @Test
- public void duplicateMnemonics_bothGetStored() throws Exception {
- builder.strategyByMnemonicMap().put("Spawn1", "ac1");
- builder.strategyByMnemonicMap().put("Spawn1", "ac2");
- SpawnActionContextMaps maps = builder.build();
- List<SpawnStrategy> result = maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
- assertThat(result).containsExactly(ac1, ac2);
- }
-
- @Test
- public void emptyStrategyFallsBackToEmptyMnemonicNotToDefault() throws Exception {
- builder.strategyByMnemonicMap().put("Spawn1", "");
- builder.strategyByMnemonicMap().put("", "ac2");
- SpawnActionContextMaps maps = builder.build();
- List<SpawnStrategy> result = maps.getSpawnActionContexts(mockSpawn("Spawn1", null), reporter);
- assertThat(result).containsExactly(ac2);
- }
-
- @Test
- public void multipleRegexps_firstMatchWins() throws Exception {
- builder.addStrategyByRegexp(converter.convert("foo"), ImmutableList.of("ac1"));
- builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
- SpawnActionContextMaps maps = builder.build();
-
- List<SpawnStrategy> result =
- maps.getSpawnActionContexts(mockSpawn(null, "Doing something with foo/bar/baz"), reporter);
-
- assertThat(result).containsExactly(ac1);
- }
-
- @Test
- public void regexpAndMnemonic_regexpWins() throws Exception {
- builder.strategyByMnemonicMap().put("Spawn1", "ac1");
- builder.addStrategyByRegexp(converter.convert("foo/bar"), ImmutableList.of("ac2"));
- SpawnActionContextMaps maps = builder.build();
-
- List<SpawnStrategy> result =
- maps.getSpawnActionContexts(
- mockSpawn("Spawn1", "Doing something with foo/bar/baz"), reporter);
-
- assertThat(result).containsExactly(ac2);
- }
-
- @Test
- public void duplicateContext_noException() throws Exception {
- builder.strategyByContextMap().put(AC1.class, "one");
- builder.strategyByContextMap().put(AC1.class, "two");
- builder.strategyByContextMap().put(AC1.class, "");
- }
-
- private Spawn mockSpawn(String mnemonic, String message) {
- Spawn mockSpawn = Mockito.mock(Spawn.class);
- ActionExecutionMetadata mockOwner = Mockito.mock(ActionExecutionMetadata.class);
- when(mockOwner.getProgressMessage()).thenReturn(message);
- when(mockSpawn.getResourceOwner()).thenReturn(mockOwner);
- when(mockSpawn.getMnemonic()).thenReturn(mnemonic);
- return mockSpawn;
- }
-
- private static class AC1 implements SpawnStrategy {
- @Override
- public ImmutableList<SpawnResult> exec(
- Spawn spawn, ActionExecutionContext actionExecutionContext)
- throws ExecException, InterruptedException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
- return true;
- }
- }
-
- private static class AC2 implements SpawnStrategy {
- @Override
- public ImmutableList<SpawnResult> exec(
- Spawn spawn, ActionExecutionContext actionExecutionContext)
- throws ExecException, InterruptedException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean canExec(Spawn spawn, ActionContext.ActionContextRegistry actionContextRegistry) {
- return true;
- }
- }
-}