Skip to content

Commit 35e54f2

Browse files
lberkiramil-bitrise
authored andcommitted
Remove special handling of middleman actions.
Now that the only type of middleman is the runfiles one, we don't need to jump through a lot of hoops we had to for other sorts of middlemen that did not represent actual inputs to actions. MiddlemanType is kept for the time being for an easier rollback of this change, if need be. RELNOTES: Actions that create runfiles trees are now considered regular actions. This means that they are now reported in statistics, critical paths and the like. PiperOrigin-RevId: 690642037 Change-Id: I472df8a8ad8235e5c8f616c8e354a5fd4739630e
1 parent 5c3b407 commit 35e54f2

File tree

22 files changed

+110
-317
lines changed

22 files changed

+110
-317
lines changed

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

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
4343
import com.google.devtools.build.lib.skyframe.TreeArtifactValue.ArchivedRepresentation;
4444
import com.google.devtools.build.lib.vfs.OutputPermissions;
45-
import com.google.devtools.build.lib.vfs.Path;
4645
import com.google.devtools.build.lib.vfs.PathFragment;
4746
import java.io.FileNotFoundException;
4847
import java.io.IOException;
@@ -231,8 +230,8 @@ private static boolean validateArtifacts(
231230
}
232231
}
233232
for (Artifact artifact : actionInputs.toList()) {
234-
mdMap.put(
235-
artifact.getExecPathString(), getInputMetadataMaybe(inputMetadataProvider, artifact));
233+
FileArtifactValue inputMetadata = getInputMetadataMaybe(inputMetadataProvider, artifact);
234+
mdMap.put(artifact.getExecPathString(), inputMetadata);
236235
}
237236
return !Arrays.equals(MetadataDigestUtils.fromMetadata(mdMap), entry.getFileDigest());
238237
}
@@ -606,6 +605,7 @@ private boolean mustExecute(
606605
actionCache.accountMiss(MissReason.UNCONDITIONAL_EXECUTION);
607606
return true;
608607
}
608+
609609
if (entry == null) {
610610
reportNewAction(handler, action);
611611
actionCache.accountMiss(MissReason.NOT_CACHED);
@@ -657,7 +657,7 @@ private static FileArtifactValue getInputMetadataOrConstant(
657657
InputMetadataProvider inputMetadataProvider, Artifact artifact) throws IOException {
658658
FileArtifactValue metadata = inputMetadataProvider.getInputMetadata(artifact);
659659
return (metadata != null && artifact.isConstantMetadata())
660-
? ConstantMetadataValue.INSTANCE
660+
? FileArtifactValue.ConstantMetadataValue.INSTANCE
661661
: metadata;
662662
}
663663

@@ -666,7 +666,7 @@ private static FileArtifactValue getOutputMetadataOrConstant(
666666
throws IOException, InterruptedException {
667667
FileArtifactValue metadata = outputMetadataStore.getOutputMetadata(artifact);
668668
return (metadata != null && artifact.isConstantMetadata())
669-
? ConstantMetadataValue.INSTANCE
669+
? FileArtifactValue.ConstantMetadataValue.INSTANCE
670670
: metadata;
671671
}
672672

@@ -992,44 +992,4 @@ private Token(Action action) {
992992
}
993993
}
994994

995-
private static final class ConstantMetadataValue extends FileArtifactValue
996-
implements FileArtifactValue.Singleton {
997-
static final ConstantMetadataValue INSTANCE = new ConstantMetadataValue();
998-
// This needs to not be of length 0, so it is distinguishable from a missing digest when written
999-
// into a Fingerprint.
1000-
private static final byte[] DIGEST = new byte[1];
1001-
1002-
private ConstantMetadataValue() {}
1003-
1004-
@Override
1005-
public FileStateType getType() {
1006-
return FileStateType.REGULAR_FILE;
1007-
}
1008-
1009-
@Override
1010-
public byte[] getDigest() {
1011-
return DIGEST;
1012-
}
1013-
1014-
@Override
1015-
public FileContentsProxy getContentsProxy() {
1016-
throw new UnsupportedOperationException();
1017-
}
1018-
1019-
@Override
1020-
public long getSize() {
1021-
return 0;
1022-
}
1023-
1024-
@Override
1025-
public long getModifiedTime() {
1026-
return -1;
1027-
}
1028-
1029-
@Override
1030-
public boolean wasModifiedSinceDigest(Path path) {
1031-
throw new UnsupportedOperationException(
1032-
"ConstantMetadataValue doesn't support wasModifiedSinceDigest " + path.toString());
1033-
}
1034-
}
1035995
}

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

Lines changed: 0 additions & 72 deletions
This file was deleted.

src/main/java/com/google/devtools/build/lib/actions/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ java_library(
5858
"ActionKeyContext.java",
5959
"ActionLogBufferPathGenerator.java",
6060
"ActionLookupValue.java",
61-
"ActionMiddlemanEvent.java",
6261
"ActionOwner.java",
6362
"ActionProgressEvent.java",
6463
"ActionRegistry.java",
@@ -436,6 +435,7 @@ java_library(
436435
":file_metadata",
437436
":runfiles_tree",
438437
"//src/main/java/com/google/devtools/build/lib/skyframe:tree_artifact_value",
438+
"//src/main/java/com/google/devtools/build/lib/util",
439439
"//src/main/java/com/google/devtools/build/lib/util:hash_codes",
440440
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
441441
"//third_party:guava",

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -972,4 +972,46 @@ public String toString() {
972972
return "singleton marker artifact value (" + hashCode() + ")";
973973
}
974974
}
975+
976+
/** {@link FileArtifactValue} subclass for artifacts with constant metadata. A singleton. */
977+
public static final class ConstantMetadataValue extends FileArtifactValue
978+
implements FileArtifactValue.Singleton {
979+
static final ConstantMetadataValue INSTANCE = new ConstantMetadataValue();
980+
// This needs to not be of length 0, so it is distinguishable from a missing digest when written
981+
// into a Fingerprint.
982+
private static final byte[] DIGEST = new byte[1];
983+
984+
private ConstantMetadataValue() {}
985+
986+
@Override
987+
public FileStateType getType() {
988+
return FileStateType.REGULAR_FILE;
989+
}
990+
991+
@Override
992+
public byte[] getDigest() {
993+
return DIGEST;
994+
}
995+
996+
@Override
997+
public FileContentsProxy getContentsProxy() {
998+
throw new UnsupportedOperationException();
999+
}
1000+
1001+
@Override
1002+
public long getSize() {
1003+
return 0;
1004+
}
1005+
1006+
@Override
1007+
public long getModifiedTime() {
1008+
return -1;
1009+
}
1010+
1011+
@Override
1012+
public boolean wasModifiedSinceDigest(Path path) {
1013+
throw new UnsupportedOperationException(
1014+
"ConstantMetadataValue doesn't support wasModifiedSinceDigest " + path);
1015+
}
1016+
}
9751017
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
2323
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
2424
import com.google.devtools.build.lib.util.Fingerprint;
25+
import com.google.devtools.build.lib.vfs.BulkDeleter;
26+
import com.google.devtools.build.lib.vfs.Path;
2527
import javax.annotation.Nullable;
2628

2729
/**
@@ -53,7 +55,18 @@ public RunfilesTree getRunfilesTree() {
5355

5456
@Override
5557
public ActionResult execute(ActionExecutionContext actionExecutionContext) {
56-
throw new IllegalStateException("MiddlemanAction should never be executed");
58+
return ActionResult.EMPTY;
59+
}
60+
61+
@Override
62+
public void prepare(
63+
Path execRoot,
64+
ArtifactPathResolver pathResolver,
65+
@Nullable BulkDeleter bulkDeleter,
66+
boolean cleanupArchivedArtifacts) {
67+
// Runfiles trees are created as a side effect of building the output manifest, not the runfiles
68+
// tree artifact. This method is overridden so that depending on the runfiles middleman does not
69+
// delete the runfiles tree that's on the file system that someone decided it must be there.
5770
}
5871

5972
@Override

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

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

16-
/** The action type. */
16+
/** Deprecated, slated to be removed. */
1717
public enum MiddlemanType {
1818

1919
/** A normal action. */
@@ -27,6 +27,9 @@ public enum MiddlemanType {
2727
RUNFILES_MIDDLEMAN;
2828

2929
public boolean isMiddleman() {
30-
return this != NORMAL;
30+
// This value is always false, which means that in theory, the MiddlemanType enum is not useful
31+
// anymore. It's kept here to facilitate an easy rollback for the change that made the enum
32+
// unnecessary should trouble arise.
33+
return false;
3134
}
3235
}

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

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import com.google.common.base.MoreObjects;
2020
import com.google.common.collect.ImmutableList;
21+
import com.google.devtools.build.lib.actions.FileArtifactValue.ConstantMetadataValue;
2122
import com.google.devtools.build.lib.skyframe.TreeArtifactValue;
23+
import com.google.devtools.build.lib.util.Fingerprint;
2224
import com.google.devtools.build.lib.util.HashCodes;
2325
import com.google.devtools.build.skyframe.SkyValue;
2426

@@ -43,13 +45,11 @@ public interface RunfilesConsumer<T> {
4345
private final ImmutableList<TreeArtifactValue> treeValues;
4446

4547
public RunfilesArtifactValue(
46-
FileArtifactValue metadata,
4748
RunfilesTree runfilesTree,
4849
ImmutableList<Artifact> files,
4950
ImmutableList<FileArtifactValue> fileValues,
5051
ImmutableList<Artifact> trees,
5152
ImmutableList<TreeArtifactValue> treeValues) {
52-
this.metadata = checkNotNull(metadata);
5353
this.runfilesTree = checkNotNull(runfilesTree);
5454
this.files = checkNotNull(files);
5555
this.fileValues = checkNotNull(fileValues);
@@ -59,10 +59,41 @@ public RunfilesArtifactValue(
5959
files.size() == fileValues.size() && trees.size() == treeValues.size(),
6060
"Size mismatch: %s",
6161
this);
62+
63+
// Compute the digest of this runfiles tree by combining its layout and the digests of every
64+
// artifact it references.
65+
this.metadata = FileArtifactValue.createProxy(computeDigest());
66+
}
67+
68+
private byte[] computeDigest() {
69+
Fingerprint result = new Fingerprint();
70+
71+
result.addInt(runfilesTree.getMapping().size());
72+
for (var entry : runfilesTree.getMapping().entrySet()) {
73+
result.addPath(entry.getKey());
74+
result.addBoolean(entry.getValue() != null);
75+
if (entry.getValue() != null) {
76+
result.addPath(entry.getValue().getExecPath());
77+
}
78+
}
79+
80+
result.addInt(files.size());
81+
for (int i = 0; i < files.size(); i++) {
82+
FileArtifactValue value =
83+
files.get(i).isConstantMetadata() ? ConstantMetadataValue.INSTANCE : fileValues.get(i);
84+
value.addTo(result);
85+
}
86+
87+
result.addInt(trees.size());
88+
for (int i = 0; i < trees.size(); i++) {
89+
result.addBytes(treeValues.get(i).getDigest());
90+
}
91+
92+
return result.digestAndReset();
6293
}
6394

6495
public RunfilesArtifactValue withOverriddenRunfilesTree(RunfilesTree overrideTree) {
65-
return new RunfilesArtifactValue(metadata, overrideTree, files, fileValues, trees, treeValues);
96+
return new RunfilesArtifactValue(overrideTree, files, fileValues, trees, treeValues);
6697
}
6798

6899
/** Returns the data of the artifact for this value, as computed by the action cache checker. */

src/main/java/com/google/devtools/build/lib/buildtool/ExecutionProgressReceiver.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import com.google.devtools.build.lib.actions.Action;
2020
import com.google.devtools.build.lib.actions.ActionExecutionStatusReporter;
2121
import com.google.devtools.build.lib.actions.ActionLookupData;
22-
import com.google.devtools.build.lib.actions.MiddlemanType;
2322
import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
2423
import com.google.devtools.build.lib.skyframe.ActionExecutionInactivityWatchdog;
2524
import com.google.devtools.build.lib.skyframe.AspectCompletionValue;
@@ -184,7 +183,7 @@ public void actionCompleted(ActionLookupData actionLookupData) {
184183
}
185184

186185
private static boolean isActionReportWorthy(Action action) {
187-
return action.getActionType() == MiddlemanType.NORMAL;
186+
return !action.getActionType().isMiddleman();
188187
}
189188

190189
@Override

src/main/java/com/google/devtools/build/lib/metrics/criticalpath/CriticalPathComputer.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
2727
import com.google.devtools.build.lib.actions.ActionCompletionEvent;
2828
import com.google.devtools.build.lib.actions.ActionKeyContext;
29-
import com.google.devtools.build.lib.actions.ActionMiddlemanEvent;
3029
import com.google.devtools.build.lib.actions.ActionStartedEvent;
3130
import com.google.devtools.build.lib.actions.Actions;
3231
import com.google.devtools.build.lib.actions.AggregatedSpawnMetrics;
@@ -234,23 +233,6 @@ public void actionStarted(ActionStartedEvent event) throws InterruptedException
234233
tryAddComponent(createComponent(action, event.getNanoTimeStart())).startRunning();
235234
}
236235

237-
/**
238-
* Record a middleman action execution. Even if middleman are almost instant, we record them
239-
* because they depend on other actions and we need them for constructing the critical path.
240-
*
241-
* <p>For some rules with incorrect configuration transitions we might get notified several times
242-
* for the same middleman. This should only happen if the actions are shared.
243-
*/
244-
@Subscribe
245-
@AllowConcurrentEvents
246-
public void middlemanAction(ActionMiddlemanEvent event) throws InterruptedException {
247-
Action action = event.getAction();
248-
CriticalPathComponent component =
249-
tryAddComponent(createComponent(action, event.getNanoTimeStart()));
250-
finalizeActionStat(
251-
event.getNanoTimeStart(), event.getNanoTimeFinish(), action, component, "middleman action");
252-
}
253-
254236
/**
255237
* Try to add the component to the map of critical path components. If there is an existing
256238
* component for its primary output it uses that to update the rest of the outputs.

0 commit comments

Comments
 (0)