When falling back from a reduced classpath Java compilation, delete outputs and generated digests before executing the fallback. RELNOTES: None. PiperOrigin-RevId: 235001623
diff --git a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java index fc61397..c48d5bc 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/actions/cache/MetadataHandler.java
@@ -82,4 +82,10 @@ * <p>Must be called at most once on any specific instance. */ void discardOutputMetadata(); + + /** + * Discards output artifact metadata and removes them from other data structures. Use this if an + * action can make multiple attempts that are expected to create the same set of output files. + */ + void resetOutputs(Iterable<Artifact> outputs); }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java index db44244..cdfc4a7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/java/JavaCompileAction.java
@@ -315,7 +315,11 @@ } } - // Fall back to running with the full classpath. + // Fall back to running with the full classpath. This requires first deleting potential + // artifacts generated by the reduced action and clearing the metadata caches. + deleteOutputs( + actionExecutionContext.getFileSystem(), actionExecutionContext.getExecRoot()); + actionExecutionContext.getMetadataHandler().resetOutputs(getOutputs()); List<SpawnResult> fallbackResults = spawnActionContext.exec( getReducedSpawn(actionExecutionContext, reducedClasspath, /* fallback=*/ true),
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java index a2c2c06..67931c7 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandler.java
@@ -510,6 +510,16 @@ store.clear(); } + @Override + public void resetOutputs(Iterable<Artifact> outputs) { + Preconditions.checkState( + executionMode.get(), "resetOutputs() should only be called from within a running action."); + for (Artifact output : outputs) { + omittedOutputs.remove(output); + store.remove(output); + } + } + OutputStore getOutputStore() { return store; }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java b/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java index 7829819..60a0ef2 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/OutputStore.java
@@ -184,4 +184,13 @@ treeArtifactContents.clear(); injectedFiles.clear(); } + + /** Clears data about a specific Artifact from this store. */ + final void remove(Artifact artifact) { + artifactData.remove(artifact); + treeArtifactData.remove(artifact); + additionalOutputData.remove(artifact); + treeArtifactContents.remove(artifact); + injectedFiles.remove(artifact); + } }
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java index fdfff3b..4f46062 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java +++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
@@ -754,5 +754,10 @@ public void discardOutputMetadata() { throw new UnsupportedOperationException(); } + + @Override + public void resetOutputs(Iterable<Artifact> outputs) { + throw new UnsupportedOperationException(); + } } }
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java index 89ac11c..eab3acf 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java +++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionMetadataHandlerTest.java
@@ -248,4 +248,32 @@ } catch (IllegalStateException expected) { } } + + @Test + public void resettingOutputs() throws Exception { + scratch.file("/output/bin/foo/bar", "not empty"); + PathFragment path = PathFragment.create("foo/bar"); + Artifact artifact = new Artifact(path, outputRoot); + ActionInputMap map = new ActionInputMap(1); + ActionMetadataHandler handler = + new ActionMetadataHandler( + map, + /* missingArtifactsAllowed= */ true, + /* outputs= */ ImmutableList.of(artifact), + /* tsgm= */ null, + ArtifactPathResolver.IDENTITY, + new MinimalOutputStore()); + handler.discardOutputMetadata(); + + // The handler doesn't have any info. It'll stat the file and discover that it's 10 bytes long. + assertThat(handler.getMetadata(artifact).getSize()).isEqualTo(10); + + // Inject a remote file of size 42. + handler.injectRemoteFile(artifact, new byte[] {1, 2, 3}, 42, 0); + assertThat(handler.getMetadata(artifact).getSize()).isEqualTo(42); + + // Reset this output, which will make the handler stat the file again. + handler.resetOutputs(ImmutableList.of(artifact)); + assertThat(handler.getMetadata(artifact).getSize()).isEqualTo(10); + } }