Make spawn id consistent in the debug log of dynamic execution.
Also removed rate-limited but unconditional logs that are not needed anymore.
PiperOrigin-RevId: 430695139
diff --git a/src/main/java/com/google/devtools/build/lib/dynamic/BUILD b/src/main/java/com/google/devtools/build/lib/dynamic/BUILD
index b781e21..e18c75c 100644
--- a/src/main/java/com/google/devtools/build/lib/dynamic/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/dynamic/BUILD
@@ -17,6 +17,7 @@
"//src/main/java/com/google/devtools/build/lib:build-request-options",
"//src/main/java/com/google/devtools/build/lib:runtime",
"//src/main/java/com/google/devtools/build/lib/actions",
+ "//src/main/java/com/google/devtools/build/lib/actions:artifacts",
"//src/main/java/com/google/devtools/build/lib/actions:execution_requirements",
"//src/main/java/com/google/devtools/build/lib/concurrent",
"//src/main/java/com/google/devtools/build/lib/events",
diff --git a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java
index accd03b..84706f9 100644
--- a/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategy.java
@@ -25,6 +25,8 @@
import com.google.common.util.concurrent.MoreExecutors;
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.Artifact;
import com.google.devtools.build.lib.actions.DynamicStrategyRegistry;
import com.google.devtools.build.lib.actions.DynamicStrategyRegistry.DynamicMode;
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
@@ -52,7 +54,6 @@
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
@@ -221,10 +222,7 @@
return nonDynamicResults;
}
- // Extra logging to debug b/194373457
- logger.atInfo().atMostEvery(1, TimeUnit.SECONDS).log(
- "Spawn %s dynamically executed both ways", spawn.getResourceOwner().describe());
- debugLog("Dynamic execution of %s beginning%n", spawn.getResourceOwner().prettyPrint());
+ debugLog("Dynamic execution of %s beginning%n", getSpawnReadableId(spawn));
// else both can exec. Fallthrough to below.
AtomicReference<DynamicMode> strategyThatCancelled = new AtomicReference<>(null);
@@ -265,14 +263,9 @@
tryScheduleLocalJob();
}
}
- logger.atInfo().atMostEvery(1, TimeUnit.SECONDS).log(
- "Dynamic execution of %s ended with local %s, remote %s%n",
- spawn.getResourceOwner().prettyPrint(),
- localBranch.isCancelled() ? "cancelled" : "done",
- remoteBranch.isCancelled() ? "cancelled" : "done");
debugLog(
"Dynamic execution of %s ended with local %s, remote %s%n",
- spawn.getResourceOwner().prettyPrint(),
+ getSpawnReadableId(spawn),
localBranch.isCancelled() ? "cancelled" : "done",
remoteBranch.isCancelled() ? "cancelled" : "done");
}
@@ -382,35 +375,21 @@
.build();
debugLog(
"Dynamic execution of %s can be done neither locally nor remotely%n",
- spawn.getResourceOwner().prettyPrint());
+ getSpawnReadableId(spawn));
throw new UserExecException(failure);
} else if (!localCanExec && remoteCanExec) {
- // Extra logging to debug b/194373457
- logger.atInfo().atMostEvery(1, TimeUnit.SECONDS).log(
- "Dynamic execution of %s can only be done remotely: Local execution policy %s it, "
- + "local strategies are %s.%n",
- spawn.getResourceOwner().prettyPrint(),
- executionPolicy.canRunLocally() ? "allows" : "forbids",
- dynamicStrategyRegistry.getDynamicSpawnActionContexts(spawn, DynamicMode.LOCAL));
debugLog(
"Dynamic execution of %s can only be done remotely: Local execution policy %s it, "
+ "local strategies are %s.%n",
- spawn.getResourceOwner().prettyPrint(),
+ getSpawnReadableId(spawn),
executionPolicy.canRunLocally() ? "allows" : "forbids",
dynamicStrategyRegistry.getDynamicSpawnActionContexts(spawn, DynamicMode.LOCAL));
return RemoteBranch.runRemotely(spawn, actionExecutionContext, null, delayLocalExecution);
} else if (localCanExec && !remoteCanExec) {
- // Extra logging to debug b/194373457
- logger.atInfo().atMostEvery(1, TimeUnit.SECONDS).log(
- "Dynamic execution of %s can only be done locally: Remote execution policy %s it, "
- + "remote strategies are %s.%n",
- spawn.getResourceOwner().prettyPrint(),
- executionPolicy.canRunRemotely() ? "allows" : "forbids",
- dynamicStrategyRegistry.getDynamicSpawnActionContexts(spawn, REMOTE));
debugLog(
"Dynamic execution of %s can only be done locally: Remote execution policy %s it, "
+ "remote strategies are %s.%n",
- spawn.getResourceOwner().prettyPrint(),
+ getSpawnReadableId(spawn),
executionPolicy.canRunRemotely() ? "allows" : "forbids",
dynamicStrategyRegistry.getDynamicSpawnActionContexts(spawn, REMOTE));
return LocalBranch.runLocally(
@@ -503,7 +482,7 @@
Event.info(
String.format(
"Cancelling remote branch of %s after local exception %s",
- spawn.getResourceOwner().prettyPrint(), e.getMessage())));
+ getSpawnReadableId(spawn), e.getMessage())));
}
remoteBranch.cancel();
throw e;
@@ -515,9 +494,7 @@
throw new AssertionError(
String.format(
"Neither branch of %s cancelled the other one. Local was %s and remote was %s.",
- spawn.getResourceOwner().getPrimaryOutput().prettyPrint(),
- localBranch.branchState(),
- remoteBranch.branchState()));
+ getSpawnReadableId(spawn), localBranch.branchState(), remoteBranch.branchState()));
} else if (localResult != null) {
return localResult;
} else if (remoteResult != null) {
@@ -528,9 +505,7 @@
throw new AssertionError(
String.format(
"Neither branch of %s completed. Local was %s and remote was %s.",
- spawn.getResourceOwner().getPrimaryOutput().prettyPrint(),
- localBranch.branchState(),
- remoteBranch.branchState()));
+ getSpawnReadableId(spawn), localBranch.branchState(), remoteBranch.branchState()));
}
}
@@ -558,9 +533,8 @@
.handle(
Event.info(
String.format(
- "Null results from %s branch of %s",
- mode,
- branch.getSpawn().getResourceOwner().getPrimaryOutput().prettyPrint())));
+ "Null results from %s branch of %s",
+ mode, getSpawnReadableId(branch.getSpawn()))));
}
return spawnResults;
} catch (CancellationException e) {
@@ -571,8 +545,7 @@
Event.info(
String.format(
"CancellationException of %s branch of %s, returning null",
- mode,
- branch.getSpawn().getResourceOwner().getPrimaryOutput().prettyPrint())));
+ mode, getSpawnReadableId(branch.getSpawn()))));
}
return null;
} catch (ExecutionException e) {
@@ -591,8 +564,7 @@
String.format(
"Caught InterruptedException from ExecException for %s branch of %s, which"
+ " may cause a crash.",
- mode,
- branch.getSpawn().getResourceOwner().getPrimaryOutput().prettyPrint())));
+ mode, getSpawnReadableId(branch.getSpawn()))));
return null;
} else {
// Even though we cannot enforce this in the future's signature (but we do in Branch#call),
@@ -661,9 +633,9 @@
.handle(
Event.info(
String.format(
- "%s action finished %sly and was %s",
- cancellingBranch.getSpawn().getMnemonic(),
+ "%s branch of %s finished and was %s",
strategyThatCancelled.get(),
+ getSpawnReadableId(cancellingBranch.getSpawn()),
cancellingBranch.isCancelled() ? "cancelled" : "not cancelled")));
}
@@ -712,4 +684,24 @@
public String toString() {
return "dynamic";
}
+
+ private static String getSpawnReadableId(Spawn spawn) {
+ ActionExecutionMetadata action = spawn.getResourceOwner();
+ if (action == null) {
+ return spawn.getMnemonic();
+ }
+
+ Artifact primaryOutput = action.getPrimaryOutput();
+ // In some cases, primary output could be null despite the method promises. And in that case, we
+ // can't use action.prettyPrint as it assumes a non-null primary output.
+ if (primaryOutput == null) {
+ String label = "";
+ if (action.getOwner() != null && action.getOwner().getLabel() != null) {
+ label = " " + action.getOwner().getLabel().toString();
+ }
+ return spawn.getMnemonic() + label;
+ }
+
+ return primaryOutput.prettyPrint();
+ }
}
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 da711eb8..3096db2 100644
--- a/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/dynamic/BUILD
@@ -25,6 +25,7 @@
"//src/main/java/com/google/devtools/build/lib/vfs",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//src/main/protobuf:failure_details_java_proto",
+ "//src/test/java/com/google/devtools/build/lib/actions/util",
"//src/test/java/com/google/devtools/build/lib/exec/util",
"//src/test/java/com/google/devtools/build/lib/testutil",
"//src/test/java/com/google/devtools/build/lib/testutil:TestUtils",
diff --git a/src/test/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategyUnitTest.java b/src/test/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategyUnitTest.java
index c76eddf..62063a4 100644
--- a/src/test/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategyUnitTest.java
+++ b/src/test/java/com/google/devtools/build/lib/dynamic/DynamicSpawnStrategyUnitTest.java
@@ -29,6 +29,7 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
+import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.Artifact.SourceArtifact;
import com.google.devtools.build.lib.actions.ArtifactRoot;
import com.google.devtools.build.lib.actions.ArtifactRoot.RootType;
@@ -41,6 +42,7 @@
import com.google.devtools.build.lib.actions.SpawnResult;
import com.google.devtools.build.lib.actions.SpawnResult.Status;
import com.google.devtools.build.lib.actions.UserExecException;
+import com.google.devtools.build.lib.actions.util.ActionsTestUtil;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.exec.ExecutionPolicy;
@@ -85,12 +87,24 @@
private Scratch scratch;
private Path execDir;
private ArtifactRoot rootDir;
+ private Artifact output1;
+ private Artifact output2;
@Before
public void initMocks() throws IOException {
scratch = new Scratch();
execDir = scratch.dir("/base/exec");
rootDir = ArtifactRoot.asDerivedRoot(execDir, RootType.Output, "root");
+ output1 =
+ Artifact.DerivedArtifact.create(
+ rootDir,
+ rootDir.getExecPath().getRelative("dir/output1.txt"),
+ ActionsTestUtil.NULL_ARTIFACT_OWNER);
+ output2 =
+ Artifact.DerivedArtifact.create(
+ rootDir,
+ rootDir.getExecPath().getRelative("dir/output2.txt"),
+ ActionsTestUtil.NULL_ARTIFACT_OWNER);
MockitoAnnotations.initMocks(this);
// Mockito can't see that we want the function to return Optional.empty() instead
// of null on apply by default (thanks generic type erasure). Set that up ourselves.
@@ -119,7 +133,7 @@
when(remote.exec(remoteSpawnCaptor.capture(), any(), any()))
.thenReturn(ImmutableList.of(SUCCESSFUL_SPAWN_RESULT));
ActionExecutionContext actionExecutionContext = createMockActionExecutionContext(local, remote);
- Spawn spawn = new SpawnBuilder().build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
ImmutableList<SpawnResult> results = dynamicSpawnStrategy.exec(spawn, actionExecutionContext);
@@ -131,7 +145,8 @@
@Test
public void exec_remoteOnlySpawn_noneCanExec_fails() throws Exception {
- Spawn spawn = new SpawnBuilder().withMnemonic("TheThing").build();
+ Spawn spawn =
+ new SpawnBuilder().withMnemonic("TheThing").withOwnerPrimaryOutput(output1).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(
ExecutionPolicy.REMOTE_EXECUTION_ONLY, mockGetPostProcessingSpawn);
@@ -153,8 +168,9 @@
@Test
public void exec_localOnlySpawn_runsLocalPostProcessingSpawn() throws Exception {
- Spawn spawn = new SpawnBuilder("command").build();
- Spawn postProcessingSpawn = new SpawnBuilder("extra_command").build();
+ Spawn spawn = new SpawnBuilder("command").withOwnerPrimaryOutput(output1).build();
+ Spawn postProcessingSpawn =
+ new SpawnBuilder("extra_command").withOwnerPrimaryOutput(output2).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(
ExecutionPolicy.LOCAL_EXECUTION_ONLY, ignored -> Optional.of(postProcessingSpawn));
@@ -187,7 +203,8 @@
@Test
public void exec_localOnlySpawn_noneCanExec_fails() throws Exception {
- Spawn spawn = new SpawnBuilder().withMnemonic("TheThing").build();
+ Spawn spawn =
+ new SpawnBuilder().withMnemonic("TheThing").withOwnerPrimaryOutput(output1).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(
ExecutionPolicy.LOCAL_EXECUTION_ONLY, mockGetPostProcessingSpawn);
@@ -230,7 +247,7 @@
.thenReturn(ImmutableList.of(failedResult));
SandboxedSpawnStrategy remote = createMockSpawnStrategy();
ActionExecutionContext actionExecutionContext = createMockActionExecutionContext(local, remote);
- Spawn spawn = new SpawnBuilder().build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
ImmutableList<SpawnResult> results = dynamicSpawnStrategy.exec(spawn, actionExecutionContext);
@@ -241,8 +258,9 @@
@Test
public void exec_runAnywhereSpawn_runsLocalPostProcessingSpawn() throws Exception {
- Spawn spawn = new SpawnBuilder().build();
- Spawn postProcessingSpawn = new SpawnBuilder("extra_command").build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
+ Spawn postProcessingSpawn =
+ new SpawnBuilder("extra_command").withOwnerPrimaryOutput(output2).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(
ExecutionPolicy.ANYWHERE, ignored -> Optional.of(postProcessingSpawn));
@@ -278,7 +296,7 @@
@Test
public void exec_runAnywhereSpawn_allowsIgnoringFailure() throws Exception {
- Spawn spawn = new SpawnBuilder().build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
checkState(
executorServiceForCleanup == null,
"Creating the DynamicSpawnStrategy twice in the same test is not supported.");
@@ -325,7 +343,7 @@
@Test
public void exec_runAnywhereSpawn_notAlwaysIgnoringFailure() throws Exception {
- Spawn spawn = new SpawnBuilder().build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
checkState(
executorServiceForCleanup == null,
"Creating the DynamicSpawnStrategy twice in the same test is not supported.");
@@ -372,7 +390,8 @@
@Test
public void exec_localOnlySpawn_skipFirst_isRun() throws Exception {
- Spawn spawn = new SpawnBuilder().withMnemonic("TheThing").build();
+ Spawn spawn =
+ new SpawnBuilder().withMnemonic("TheThing").withOwnerPrimaryOutput(output1).build();
DynamicExecutionOptions options = new DynamicExecutionOptions();
options.skipFirstBuild = true;
DynamicSpawnStrategy dynamicSpawnStrategy =
@@ -391,7 +410,8 @@
@Test
public void exec_runAnywhereSpawn_skipFirst_onlyRemote() throws Exception {
- Spawn spawn = new SpawnBuilder().withMnemonic("TheThing").build();
+ Spawn spawn =
+ new SpawnBuilder().withMnemonic("TheThing").withOwnerPrimaryOutput(output1).build();
DynamicExecutionOptions options = new DynamicExecutionOptions();
options.skipFirstBuild = true;
DynamicSpawnStrategy dynamicSpawnStrategy =
@@ -450,7 +470,7 @@
@Test
public void exec_runAnywhereSpawn_localCantExec_runsRemote() throws Exception {
- Spawn spawn = new SpawnBuilder().build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(ExecutionPolicy.ANYWHERE, mockGetPostProcessingSpawn);
SandboxedSpawnStrategy local = createMockSpawnStrategy(false);
@@ -476,8 +496,9 @@
@Test
public void exec_runAnywhereSpawn_remoteCantExec_runsLocal() throws Exception {
- Spawn spawn = new SpawnBuilder().build();
- Spawn postProcessingSpawn = new SpawnBuilder("extra_command").build();
+ Spawn spawn = new SpawnBuilder().withOwnerPrimaryOutput(output1).build();
+ Spawn postProcessingSpawn =
+ new SpawnBuilder("extra_command").withOwnerPrimaryOutput(output2).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(
ExecutionPolicy.ANYWHERE, ignored -> Optional.of(postProcessingSpawn));
@@ -506,7 +527,8 @@
@Test
public void exec_runAnywhereSpawn_noneCanExec_fails() throws Exception {
- Spawn spawn = new SpawnBuilder().withMnemonic("TheThing").build();
+ Spawn spawn =
+ new SpawnBuilder().withMnemonic("TheThing").withOwnerPrimaryOutput(output1).build();
DynamicSpawnStrategy dynamicSpawnStrategy =
createDynamicSpawnStrategy(ExecutionPolicy.ANYWHERE, mockGetPostProcessingSpawn);
SandboxedSpawnStrategy local = createMockSpawnStrategy(false);