Incorporate skymeld inconsistencies into the rewinding/node dropping receivers.
Current state: blaze in skymeld + rewinding just uses the `RewindableGraphInconsistencyReceiver`, which doesn't take into account skymeld inconsistencies and is mutually exclusive with `SkymeldInconsistencyReceiver`.
After this CL: `RewindableGraphInconsistencyReceiver` and `NodeDroppingInconsistencyReceiver` handles skymeld-specific inconsistencies as well.
Code changes:
- `SkymeldInconsistencyReceiver` is removed and its content is distributed to the rewinding/node dropping inconsistency receivers.
Behavior changes:
- `RewindableGraphInconsistencyReceiver` and `NodeDroppingInconsistencyReceiver` handles skymeld-specific inconsistencies as well.
- Unexpected skymeld inconsistencies will throw, instead of sending a BugReport like before.
---
Since https://github.com/bazelbuild/bazel/commit/5b52f018b193be02fd11de9bc89c9f9d49bf5b3f, rewinding is already compatible with Skymeld.
PiperOrigin-RevId: 631332866
Change-Id: I3d222c23d5e40aa7a86546039bfb795f7b812c2c
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
index a1b0f79..df4c63f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/BUILD
@@ -187,7 +187,6 @@
":skyframe_executor_repository_helpers_holder",
":skyframe_incremental_build_monitor",
":skyframe_stats",
- ":skymeld_inconsistency_receiver",
":starlark_builtins_value",
":state_informing_sky_function_environment",
":target_completion_value",
@@ -3194,21 +3193,6 @@
)
java_library(
- name = "skymeld_inconsistency_receiver",
- srcs = ["SkymeldInconsistencyReceiver.java"],
- deps = [
- ":node_dropping_inconsistency_receiver",
- ":sky_functions",
- "//src/main/java/com/google/devtools/build/lib/bugreport",
- "//src/main/java/com/google/devtools/build/skyframe",
- "//src/main/java/com/google/devtools/build/skyframe:graph_inconsistency_java_proto",
- "//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
- "//third_party:guava",
- "//third_party:jsr305",
- ],
-)
-
-java_library(
name = "sky_key_stats",
srcs = ["SkyKeyStats.java"],
)
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/NodeDroppingInconsistencyReceiver.java b/src/main/java/com/google/devtools/build/lib/skyframe/NodeDroppingInconsistencyReceiver.java
index 5283fa8..ebdf9dc 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/NodeDroppingInconsistencyReceiver.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/NodeDroppingInconsistencyReceiver.java
@@ -13,7 +13,6 @@
// limitations under the License.
package com.google.devtools.build.lib.skyframe;
-import static com.google.common.base.Preconditions.checkState;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.FileValue;
@@ -28,31 +27,51 @@
/**
* {@link GraphInconsistencyReceiver} for evaluations operating on graphs when {@code
- * --heuristically_drop_nodes} flag is applied.
+ * --heuristically_drop_nodes} flag is applied, or when some form of node dropping is done in
+ * combination with skymeld mode.
*
- * <p>The expected inconsistency caused by heuristically dropping state nodes should be tolerated
- * while all other inconsistencies should result in throwing an exception.
+ * <p>The expected inconsistency should be tolerated while all other inconsistencies should result
+ * in throwing an exception.
*
* <p>{@code RewindableGraphInconsistencyReceiver} implements similar logic to handle heuristically
* dropping state nodes.
*/
-public class NodeDroppingInconsistencyReceiver implements GraphInconsistencyReceiver {
+public final class NodeDroppingInconsistencyReceiver implements GraphInconsistencyReceiver {
+ private final boolean heuristicallyDropNodes;
+ private final boolean skymeldInconsistenciesExpected;
private static final ImmutableMap<SkyFunctionName, SkyFunctionName> EXPECTED_MISSING_CHILDREN =
ImmutableMap.of(
FileValue.FILE, FileStateKey.FILE_STATE,
SkyFunctions.DIRECTORY_LISTING, SkyFunctions.DIRECTORY_LISTING_STATE,
SkyFunctions.CONFIGURED_TARGET, GenQueryDirectPackageProviderFactory.GENQUERY_SCOPE);
+ // TODO: b/290998109#comment60 - After the GLOB nodes are replaced by GLOBS, the missing children
+ // below might be unexpected.
+ // These are only expected when Skymeld is enabled and we're dropping nodes.
+ private static final ImmutableMap<SkyFunctionName, SkyFunctionName>
+ SKYMELD_EXPECTED_MISSING_CHILDREN =
+ ImmutableMap.of(SkyFunctions.ACTION_EXECUTION, SkyFunctions.GLOB);
+
+ public NodeDroppingInconsistencyReceiver(
+ boolean heuristicallyDropNodes, boolean skymeldInconsistenciesExpected) {
+ this.heuristicallyDropNodes = heuristicallyDropNodes;
+ this.skymeldInconsistenciesExpected = skymeldInconsistenciesExpected;
+ }
+
@Override
public void noteInconsistencyAndMaybeThrow(
SkyKey key, @Nullable Collection<SkyKey> otherKeys, Inconsistency inconsistency) {
- checkState(
- isExpectedInconsistency(key, otherKeys, inconsistency),
- "Unexpected inconsistency: %s, %s, %s",
- key,
- otherKeys,
- inconsistency);
+ if (heuristicallyDropNodes && isExpectedInconsistency(key, otherKeys, inconsistency)) {
+ return;
+ }
+ if (skymeldInconsistenciesExpected
+ && isExpectedInconsistencySkymeld(key, otherKeys, inconsistency)) {
+ return;
+ }
+
+ throw new IllegalStateException(
+ String.format("Unexpected inconsistency: %s, %s, %s", key, otherKeys, inconsistency));
}
/**
@@ -61,19 +80,40 @@
*/
public static boolean isExpectedInconsistency(
SkyKey key, @Nullable Collection<SkyKey> otherKeys, Inconsistency inconsistency) {
- return isExpectedInconsistency(key, otherKeys, inconsistency, EXPECTED_MISSING_CHILDREN);
+ return isExpectedInternal(
+ key,
+ otherKeys,
+ inconsistency,
+ EXPECTED_MISSING_CHILDREN,
+ /* isSkymeldInconsistency= */ false);
}
- static boolean isExpectedInconsistency(
+ /**
+ * Checks whether the input inconsistency is an expected scenario caused by skymeld + some form of
+ * node dropping.
+ */
+ public static boolean isExpectedInconsistencySkymeld(
+ SkyKey key, @Nullable Collection<SkyKey> otherKeys, Inconsistency inconsistency) {
+ return isExpectedInternal(
+ key,
+ otherKeys,
+ inconsistency,
+ SKYMELD_EXPECTED_MISSING_CHILDREN,
+ /* isSkymeldInconsistency= */ true);
+ }
+
+ private static boolean isExpectedInternal(
SkyKey key,
@Nullable Collection<SkyKey> otherKeys,
Inconsistency inconsistency,
- ImmutableMap<SkyFunctionName, SkyFunctionName> expectedMissingChildrenTypes) {
- SkyFunctionName expectedMissingChildType = expectedMissingChildrenTypes.get(key.functionName());
+ ImmutableMap<SkyFunctionName, SkyFunctionName> expectedMissingChildTypes,
+ boolean isSkymeldInconsistency) {
+ SkyFunctionName expectedMissingChildType = expectedMissingChildTypes.get(key.functionName());
if (expectedMissingChildType == null) {
return false;
}
- if (inconsistency == Inconsistency.RESET_REQUESTED) {
+ // Skymeld shouldn't cause any inconsistency of this type.
+ if (!isSkymeldInconsistency && inconsistency == Inconsistency.RESET_REQUESTED) {
return otherKeys == null;
}
if (inconsistency == Inconsistency.ALREADY_DECLARED_CHILD_MISSING
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
index faade35..38ce06c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
@@ -298,28 +298,27 @@
}
private GraphInconsistencyReceiver getGraphInconsistencyReceiverForCommand(
- OptionsProvider options) throws AbruptExitException {
- if (rewindingEnabled(options)) {
- // Currently incompatible with Skymeld i.e. this code path won't be run in Skymeld mode. We
- // may need to combine these GraphInconsistencyReceiver implementations in the future.
- var rewindableReceiver = new RewindableGraphInconsistencyReceiver();
- rewindableReceiver.setHeuristicallyDropNodes(heuristicallyDropNodes);
- return rewindableReceiver;
- }
- if (isMergedSkyframeAnalysisExecution()
- && ((options.getOptions(AnalysisOptions.class) != null
+ OptionsProvider options) {
+ var someNodeDroppingExpected =
+ (options.getOptions(AnalysisOptions.class) != null
&& options.getOptions(AnalysisOptions.class).discardAnalysisCache)
|| !trackIncrementalState
- || heuristicallyDropNodes)) {
- return new SkymeldInconsistencyReceiver(heuristicallyDropNodes);
+ || heuristicallyDropNodes;
+ var skymeldInconsistenciesExpected =
+ someNodeDroppingExpected && isMergedSkyframeAnalysisExecution();
+ if (rewindingEnabled(options)) {
+ return new RewindableGraphInconsistencyReceiver(
+ heuristicallyDropNodes, skymeldInconsistenciesExpected);
}
- if (heuristicallyDropNodes) {
- return new NodeDroppingInconsistencyReceiver();
+
+ if (heuristicallyDropNodes || skymeldInconsistenciesExpected) {
+ return new NodeDroppingInconsistencyReceiver(
+ heuristicallyDropNodes, skymeldInconsistenciesExpected);
}
return GraphInconsistencyReceiver.THROWING;
}
- private boolean rewindingEnabled(OptionsProvider options) throws AbruptExitException {
+ private boolean rewindingEnabled(OptionsProvider options) {
var buildRequestOptions = options.getOptions(BuildRequestOptions.class);
return buildRequestOptions != null && buildRequestOptions.rewindLostInputs;
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkymeldInconsistencyReceiver.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkymeldInconsistencyReceiver.java
deleted file mode 100644
index 7f57eef..0000000
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkymeldInconsistencyReceiver.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2023 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.skyframe;
-
-
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.bugreport.BugReport;
-import com.google.devtools.build.skyframe.GraphInconsistencyReceiver;
-import com.google.devtools.build.skyframe.SkyFunctionName;
-import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.proto.GraphInconsistency.Inconsistency;
-import java.util.Collection;
-import javax.annotation.Nullable;
-
-/**
- * The {@link GraphInconsistencyReceiver} that tolerates inconsistencies resulted in dropping
- * pre-execution nodes in Skymeld mode.
- */
-public class SkymeldInconsistencyReceiver implements GraphInconsistencyReceiver {
- // TODO: b/290998109#comment60 - After the GLOB nodes are replaced by GLOBS, the missing children
- // below might be unexpected.
- private static final ImmutableMap<SkyFunctionName, SkyFunctionName>
- SKYMELD_EXPECTED_MISSING_CHILDREN =
- ImmutableMap.of(SkyFunctions.ACTION_EXECUTION, SkyFunctions.GLOB);
-
- private final boolean heuristicallyDropNodes;
-
- public SkymeldInconsistencyReceiver(boolean heuristicallyDropNodes) {
- this.heuristicallyDropNodes = heuristicallyDropNodes;
- }
-
- @Override
- public void noteInconsistencyAndMaybeThrow(
- SkyKey key, @Nullable Collection<SkyKey> otherKeys, Inconsistency inconsistency) {
- if (heuristicallyDropNodes
- && NodeDroppingInconsistencyReceiver.isExpectedInconsistency(
- key, otherKeys, inconsistency)) {
- // If `--heuristically_drop_nodes` is enabled, check whether the inconsistency is caused by
- // dropped state node. If so, tolerate the inconsistency and return.
- return;
- }
-
- if (!NodeDroppingInconsistencyReceiver.isExpectedInconsistency(
- key, otherKeys, inconsistency, SKYMELD_EXPECTED_MISSING_CHILDREN)) {
- // Instead of crashing, simply send a bug report here so we can evaluate whether this is an
- // actual bug or just something else to be added to the expected list.
- BugReport.logUnexpected(
- "Unexpected inconsistency: %s, %s, %s", key, otherKeys, inconsistency);
- }
- }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/rewinding/RewindableGraphInconsistencyReceiver.java b/src/main/java/com/google/devtools/build/lib/skyframe/rewinding/RewindableGraphInconsistencyReceiver.java
index 7b01edf..86ee46a 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/rewinding/RewindableGraphInconsistencyReceiver.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/rewinding/RewindableGraphInconsistencyReceiver.java
@@ -52,10 +52,13 @@
private final Multiset<Inconsistency> selfCounts = ConcurrentHashMultiset.create();
private final Multiset<Inconsistency> childCounts = ConcurrentHashMultiset.create();
private boolean rewindingInitiated = false;
- private boolean heuristicallyDropNodes = false;
+ private final boolean heuristicallyDropNodes;
+ private final boolean skymeldInconsistenciesExpected;
- public void setHeuristicallyDropNodes(boolean heuristicallyDropNodes) {
+ public RewindableGraphInconsistencyReceiver(
+ boolean heuristicallyDropNodes, boolean skymeldInconsistenciesExpected) {
this.heuristicallyDropNodes = heuristicallyDropNodes;
+ this.skymeldInconsistenciesExpected = skymeldInconsistenciesExpected;
}
@Override
@@ -69,6 +72,12 @@
return;
}
+ if (skymeldInconsistenciesExpected
+ && NodeDroppingInconsistencyReceiver.isExpectedInconsistencySkymeld(
+ key, otherKeys, inconsistency)) {
+ return;
+ }
+
// RESET_REQUESTED and PARENT_FORCE_REBUILD_OF_CHILD may be the first inconsistencies seen with
// rewinding. BUILDING_PARENT_FOUND_UNDONE_CHILD may also be seen, but it will not be the first.
switch (inconsistency) {