Skip to content

Commit 7c096ba

Browse files
tjgqcopybara-github
authored andcommitted
Improve the documentation for OutputMetadataStore.
Also make the getOutputMetadata argument an Artifact instead of an ActionInput, since we always cast it anyway. PiperOrigin-RevId: 832479663 Change-Id: I092f6316d217add6528803a31bc135a017926eee
1 parent b445e77 commit 7c096ba

File tree

9 files changed

+64
-50
lines changed

9 files changed

+64
-50
lines changed

src/main/java/com/google/devtools/build/lib/actions/ActionExecutionContext.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -562,18 +562,18 @@ private ActionExecutionContext withInputMetadataProvider(
562562

563563
/**
564564
* Creates a new {@link ActionExecutionContext} whose {@link InputMetadataProvider} has the given
565-
* {@link ActionInput}s as inputs.
565+
* {@link Artifact}s as inputs.
566566
*
567-
* <p>Each {@link ActionInput} must be an output of the current {@link ActionExecutionContext} and
568-
* it must already have been built.
567+
* <p>Each {@link Artifact} must be an output of the current {@link ActionExecutionContext} and it
568+
* must already have been built.
569569
*/
570-
public ActionExecutionContext withOutputsAsInputs(
571-
Iterable<? extends ActionInput> additionalInputs) throws IOException, InterruptedException {
570+
public ActionExecutionContext withOutputsAsInputs(Iterable<Artifact> outputs)
571+
throws IOException, InterruptedException {
572572
ImmutableMap.Builder<ActionInput, FileArtifactValue> additionalInputMap =
573573
ImmutableMap.builder();
574574

575-
for (ActionInput input : additionalInputs) {
576-
additionalInputMap.put(input, outputMetadataStore.getOutputMetadata(input));
575+
for (Artifact output : outputs) {
576+
additionalInputMap.put(output, outputMetadataStore.getOutputMetadata(output));
577577
}
578578

579579
StaticInputMetadataProvider additionalInputMetadata =

src/main/java/com/google/devtools/build/lib/actions/cache/OutputMetadataStore.java

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.actions.cache;
1515

16-
import com.google.devtools.build.lib.actions.ActionInput;
1716
import com.google.devtools.build.lib.actions.Artifact;
1817
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
1918
import com.google.devtools.build.lib.actions.FileArtifactValue;
2019
import com.google.devtools.build.lib.actions.FileStateType;
2120
import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
2221
import java.io.IOException;
22+
import javax.annotation.Nullable;
2323

2424
/** Handles the metadata of the outputs of the action during its execution. */
2525
public interface OutputMetadataStore {
@@ -48,27 +48,47 @@ public interface OutputMetadataStore {
4848
void injectTree(SpecialArtifact output, TreeArtifactValue tree);
4949

5050
/**
51-
* Returns a {@link FileArtifactValue} for the given {@link ActionInput}.
51+
* Returns a {@link FileArtifactValue} for the given {@link Artifact}.
5252
*
53-
* <p>If the metadata of the given {@link ActionInput} is not known, it's computed. This may
54-
* result in a significant amount of I/O.
53+
* <p>If the metadata of the given {@link Artifact} has not been injected via {@link #injectFile},
54+
* it will be computed from the filesystem. This may result in a significant amount of I/O. The
55+
* result will be cached for future calls to this method.
5556
*
56-
* <p>The returned {@link FileArtifactValue} instance corresponds to the final target of a symlink
57-
* and therefore must not have a type of {@link FileStateType#SYMLINK}.
57+
* <p>For artifacts of non-symlink type (i.e., {@link Artifact#isSymlink} returns false), the
58+
* returned {@link FileArtifactValue} corresponds to the final target of a symlink when one exists
59+
* in the filesystem, and therefore will not have a type of {@link FileStateType#SYMLINK}.
5860
*
59-
* <p>Freshly created output files (i.e. from an action that just executed) that require a stat to
60-
* obtain the metadata will first be set read-only and executable during this call. This ensures
61-
* that the returned metadata has an appropriate ctime, which is affected by chmod. Note that this
62-
* does not apply to outputs injected via {@link #injectFile} or {@link #injectTree} since a stat
63-
* is not required for them.
61+
* <p>If a stat is required to obtain the metadata, the output will first be set read-only and
62+
* executable by this call. This ensures that the returned metadata has an appropriate ctime,
63+
* which is affected by chmod. Note that this does not apply to outputs injected via {@link
64+
* #injectFile} since a stat is not required for them.
6465
*
65-
* @param output the output to retrieve the digest for
66-
* @return the artifact's digest or null the artifact is not a known output of the action
67-
* @throws IOException if the action input cannot be digested
66+
* @param artifact the artifact to retrieve metadata for
67+
* @return the artifact metadata, or null the artifact is not a known output of the action
68+
* @throws IOException if the metadata cannot be obtained from the filesystem
69+
* @throws InterruptedException if the current thread is interrupted while computing the metadata
6870
*/
69-
FileArtifactValue getOutputMetadata(ActionInput output) throws IOException, InterruptedException;
71+
@Nullable
72+
FileArtifactValue getOutputMetadata(Artifact artifact) throws IOException, InterruptedException;
7073

71-
/** Retrieves the metadata for this tree artifact. Data should already be available. */
74+
/**
75+
* Returns a {@link TreeArtifactValue} for the given {@link SpecialArtifact}, which must be a tree
76+
* artifact (i.e., {@link SpecialArtifact#isTreeArtifact} must return true).
77+
*
78+
* <p>If the metadata of the given {@link SpecialArtifact} has not been injected via {@link
79+
* #injectTree}, it will be computed from the filesystem. This may result in a significant amount
80+
* of I/O. The result will be cached for future calls to this method.
81+
*
82+
* <p>If a stat is required to obtain the metadata, the output will first be set read-only and
83+
* executable by this call. This ensures that the returned metadata has an appropriate ctime,
84+
* which is affected by chmod. Note that this does not apply to outputs injected via {@link
85+
* #injectFile} since a stat is not required for them.
86+
*
87+
* @param treeArtifact the tree artifact to retrieve metadata for
88+
* @return the tree artifact metadata
89+
* @throws IOException if the metadata cannot be obtained from the filesystem
90+
* @throws InterruptedException if the current thread is interrupted while computing the metadata
91+
*/
7292
TreeArtifactValue getTreeArtifactValue(SpecialArtifact treeArtifact)
7393
throws IOException, InterruptedException;
7494

src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
import com.google.common.collect.ImmutableMap;
2424
import com.google.common.collect.ImmutableMultimap;
2525
import com.google.common.collect.ImmutableSet;
26+
import com.google.common.collect.ImmutableSortedSet;
2627
import com.google.devtools.build.lib.actions.ActionExecutionContext;
2728
import com.google.devtools.build.lib.actions.ActionInput;
29+
import com.google.devtools.build.lib.actions.Artifact;
2830
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
31+
import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
2932
import com.google.devtools.build.lib.actions.ArtifactPathResolver;
3033
import com.google.devtools.build.lib.actions.EnvironmentalExecException;
3134
import com.google.devtools.build.lib.actions.ExecException;
@@ -754,13 +757,13 @@ private TestAttemptResult runTestAttempt(
754757
.getOutputMetadataStore()
755758
.getOutputMetadata(testAction.getCoverageDirectoryTreeArtifact());
756759

757-
ImmutableSet<? extends ActionInput> expandedCoverageDir =
760+
ImmutableSortedSet<TreeFileArtifact> expandedCoverageDir =
758761
actionExecutionContext
759762
.getOutputMetadataStore()
760763
.getTreeArtifactValue((SpecialArtifact) testAction.getCoverageDirectoryTreeArtifact())
761764
.getChildren();
762-
ImmutableSet<ActionInput> coverageSpawnMetadata =
763-
ImmutableSet.<ActionInput>builder()
765+
ImmutableSet<Artifact> coverageSpawnMetadata =
766+
ImmutableSet.<Artifact>builder()
764767
.addAll(expandedCoverageDir)
765768
.add(testAction.getCoverageDirectoryTreeArtifact())
766769
.build();

src/main/java/com/google/devtools/build/lib/remote/AbstractActionInputPrefetcher.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ enum DirectoryState {
9090
/**
9191
* Returns the metadata for an {@link ActionInput}.
9292
*
93-
* <p>This will generally call through to a {@link InputMetadataProvider} and ask for the metadata
94-
* of either an input or an output artifact.
93+
* <p>This will generally call through to a {@link InputMetadataProvider} or {@link
94+
* OutputMetadataStore} and ask for the metadata of either an input or an output artifact.
9595
*/
9696
@VisibleForTesting
9797
public interface MetadataSupplier {
@@ -762,7 +762,7 @@ public void finalizeAction(Action action, OutputMetadataStore outputMetadataStor
762762
prefetchFilesInterruptibly(
763763
action,
764764
outputsToDownload,
765-
outputMetadataStore::getOutputMetadata,
765+
output -> outputMetadataStore.getOutputMetadata((Artifact) output),
766766
Priority.HIGH,
767767
Reason.OUTPUTS));
768768
}

src/main/java/com/google/devtools/build/lib/skyframe/ActionOutputMetadataStore.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.google.common.collect.ImmutableSet;
2727
import com.google.common.collect.Sets;
2828
import com.google.common.flogger.GoogleLogger;
29-
import com.google.devtools.build.lib.actions.ActionInput;
3029
import com.google.devtools.build.lib.actions.Artifact;
3130
import com.google.devtools.build.lib.actions.Artifact.ArchivedTreeArtifact;
3231
import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
@@ -71,9 +70,9 @@
7170
* files are set read-only and executable <em>before</em> statting them to ensure that the stat's
7271
* ctime is up to date.
7372
*
74-
* <p>After action execution, {@link #getOutputMetadata} should be called on each of the action's
75-
* outputs (except those that were {@linkplain #artifactOmitted omitted}) to ensure that declared
76-
* outputs were in fact created and are valid.
73+
* <p>After action execution, {@link #getOutputMetadata} or {@link #getTreeArtifactValue} should be
74+
* called on each of the action's outputs (except those that were {@linkplain #artifactOmitted
75+
* omitted}) to ensure that declared outputs were in fact created and are valid.
7776
*/
7877
final class ActionOutputMetadataStore implements OutputMetadataStore {
7978
private static final GoogleLogger logger = GoogleLogger.forEnclosingClass();
@@ -176,18 +175,15 @@ private boolean isKnownOutput(Artifact artifact) {
176175

177176
@Nullable
178177
@Override
179-
public FileArtifactValue getOutputMetadata(ActionInput actionInput)
178+
public FileArtifactValue getOutputMetadata(Artifact artifact)
180179
throws IOException, InterruptedException {
181-
Artifact artifact = (Artifact) actionInput;
182-
FileArtifactValue value;
183-
184180
if (!isKnownOutput(artifact)) {
185181
return null;
186182
}
187183

188184
if (artifact.isRunfilesTree()) {
189185
// Runfiles trees get a placeholder value, see the Javadoc of RUNFILES_TREE_MARKER as to why
190-
value = artifactData.get(artifact);
186+
FileArtifactValue value = artifactData.get(artifact);
191187
if (value != null) {
192188
return checkExists(value, artifact);
193189
}
@@ -202,11 +198,12 @@ public FileArtifactValue getOutputMetadata(ActionInput actionInput)
202198

203199
if (artifact.isChildOfDeclaredDirectory()) {
204200
TreeArtifactValue tree = getTreeArtifactValue(artifact.getParent());
205-
value = tree.getChildValues().getOrDefault(artifact, FileArtifactValue.MISSING_FILE_MARKER);
201+
FileArtifactValue value =
202+
tree.getChildValues().getOrDefault(artifact, FileArtifactValue.MISSING_FILE_MARKER);
206203
return checkExists(value, artifact);
207204
}
208205

209-
value = artifactData.get(artifact);
206+
FileArtifactValue value = artifactData.get(artifact);
210207
if (value != null) {
211208
return checkExists(value, artifact);
212209
}

src/main/java/com/google/devtools/build/lib/skyframe/SkyframeActionExecutor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import com.google.devtools.build.lib.actions.ActionExecutionContext.LostInputsCheck;
4444
import com.google.devtools.build.lib.actions.ActionExecutionException;
4545
import com.google.devtools.build.lib.actions.ActionExecutionStatusReporter;
46-
import com.google.devtools.build.lib.actions.ActionInput;
4746
import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
4847
import com.google.devtools.build.lib.actions.ActionKeyContext;
4948
import com.google.devtools.build.lib.actions.ActionLogBufferPathGenerator;
@@ -147,7 +146,7 @@ public final class SkyframeActionExecutor {
147146
private static final OutputMetadataStore THROWING_OUTPUT_METADATA_STORE_FOR_ACTIONFS =
148147
new OutputMetadataStore() {
149148
@Override
150-
public FileArtifactValue getOutputMetadata(ActionInput output) {
149+
public FileArtifactValue getOutputMetadata(Artifact artifact) {
151150
throw new IllegalStateException();
152151
}
153152

src/test/java/com/google/devtools/build/lib/actions/ActionCacheCheckerTest.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,12 +1855,8 @@ public FileArtifactValue getInputMetadata(ActionInput input) throws IOException
18551855
}
18561856

18571857
@Override
1858-
public FileArtifactValue getOutputMetadata(ActionInput input)
1858+
public FileArtifactValue getOutputMetadata(Artifact output)
18591859
throws IOException, InterruptedException {
1860-
if (!(input instanceof Artifact output)) {
1861-
return null;
1862-
}
1863-
18641860
if (output.isTreeArtifact()) {
18651861
TreeArtifactValue treeArtifactValue = getTreeArtifactValue((SpecialArtifact) output);
18661862
if (treeArtifactValue != null) {

src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ public ImmutableList<RunfilesTree> getRunfilesTrees() {
10081008
}
10091009

10101010
@Override
1011-
public FileArtifactValue getOutputMetadata(ActionInput input)
1011+
public FileArtifactValue getOutputMetadata(Artifact artifact)
10121012
throws IOException, InterruptedException {
10131013
throw new UnsupportedOperationException();
10141014
}

src/test/java/com/google/devtools/build/lib/exec/StandaloneTestStrategyTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import com.google.devtools.build.lib.actions.ActionContext;
2929
import com.google.devtools.build.lib.actions.ActionExecutionContext;
3030
import com.google.devtools.build.lib.actions.ActionExecutionException;
31-
import com.google.devtools.build.lib.actions.ActionInput;
3231
import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
3332
import com.google.devtools.build.lib.actions.ActionKeyContext;
3433
import com.google.devtools.build.lib.actions.Artifact;
@@ -196,7 +195,7 @@ public Path getExecRoot() {
196195
}
197196

198197
@Override
199-
public ActionExecutionContext withOutputsAsInputs(Iterable<? extends ActionInput> inputs) {
198+
public ActionExecutionContext withOutputsAsInputs(Iterable<Artifact> outputs) {
200199
return this;
201200
}
202201

0 commit comments

Comments
 (0)