aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java
diff options
context:
space:
mode:
authorGravatar mschaller <mschaller@google.com>2018-07-01 21:29:19 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-07-01 21:30:22 -0700
commit4f64b77a3dd8e4ccdc8077051927985f9578a3a5 (patch)
tree29bd53b6118db8d9f6d135425d10f2842c575e74 /src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java
parentb9166943e5dc23f7ce8ef2dce3cb98e5ce26e50b (diff)
Native Skyframe support for node restarting
Useful for attempting to recover relationships between Skyframe graph state and external systems, when the evaluation of a Skyframe node has the side effect of creating that relationship. Currently, only supported in graph evaluations when reverse dependency edges are not tracked. RELNOTES: None. PiperOrigin-RevId: 202892953
Diffstat (limited to 'src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java')
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java65
1 files changed, 49 insertions, 16 deletions
diff --git a/src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java b/src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java
index 1a2cab9b4b..c2f8561c32 100644
--- a/src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java
+++ b/src/main/java/com/google/devtools/build/skyframe/AbstractParallelEvaluator.java
@@ -33,12 +33,14 @@ import com.google.devtools.build.skyframe.NodeEntry.DependencyState;
import com.google.devtools.build.skyframe.NodeEntry.DirtyState;
import com.google.devtools.build.skyframe.ParallelEvaluatorContext.EnqueueParentBehavior;
import com.google.devtools.build.skyframe.QueryableGraph.Reason;
+import com.google.devtools.build.skyframe.SkyFunction.Restart;
import com.google.devtools.build.skyframe.SkyFunctionEnvironment.UndonePreviouslyRequestedDep;
import com.google.devtools.build.skyframe.SkyFunctionException.ReifiedSkyFunctionException;
import java.time.Duration;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ForkJoinPool;
import java.util.logging.Logger;
@@ -179,8 +181,10 @@ public abstract class AbstractParallelEvaluator {
throws InterruptedException {
return depGroup.size() == 1
&& depGroup.contains(ErrorTransienceValue.KEY)
- && !graph.get(
- null, Reason.OTHER, ErrorTransienceValue.KEY).getVersion().atMost(entry.getVersion());
+ && !graph
+ .get(null, Reason.OTHER, ErrorTransienceValue.KEY)
+ .getVersion()
+ .atMost(entry.getVersion());
}
private DirtyOutcome maybeHandleDirtyNode(NodeEntry state) throws InterruptedException {
@@ -363,20 +367,21 @@ public abstract class AbstractParallelEvaluator {
Set<SkyKey> oldDeps = state.getAllRemainingDirtyDirectDeps();
SkyFunctionEnvironment env;
try {
- evaluatorContext.getProgressReceiver().stateStarting(skyKey,
- NodeState.INITIALIZING_ENVIRONMENT);
+ evaluatorContext
+ .getProgressReceiver()
+ .stateStarting(skyKey, NodeState.INITIALIZING_ENVIRONMENT);
env =
new SkyFunctionEnvironment(
skyKey, state.getTemporaryDirectDeps(), oldDeps, evaluatorContext);
} catch (UndonePreviouslyRequestedDep undonePreviouslyRequestedDep) {
// If a previously requested dep is no longer done, restart this node from scratch.
- maybeEraseNodeToRestartFromScratch(
- skyKey, state, SkyFunction.SENTINEL_FOR_RESTART_FROM_SCRATCH);
+ restart(skyKey, state);
evaluatorContext.getVisitor().enqueueEvaluation(skyKey);
return;
} finally {
- evaluatorContext.getProgressReceiver().stateEnding(skyKey,
- NodeState.INITIALIZING_ENVIRONMENT, -1);
+ evaluatorContext
+ .getProgressReceiver()
+ .stateEnding(skyKey, NodeState.INITIALIZING_ENVIRONMENT, -1);
}
SkyFunctionName functionName = skyKey.functionName();
SkyFunction factory =
@@ -476,7 +481,7 @@ public abstract class AbstractParallelEvaluator {
env.doneBuilding();
}
- if (maybeEraseNodeToRestartFromScratch(skyKey, state, value)) {
+ if (maybeHandleRestart(skyKey, state, value)) {
evaluatorContext.getVisitor().enqueueEvaluation(skyKey);
return;
}
@@ -652,15 +657,36 @@ public abstract class AbstractParallelEvaluator {
private static final int MAX_REVERSEDEP_DUMP_LENGTH = 1000;
}
- private boolean maybeEraseNodeToRestartFromScratch(
- SkyKey key, NodeEntry entry, SkyValue returnedValue) {
- if (!SkyFunction.SENTINEL_FOR_RESTART_FROM_SCRATCH.equals(returnedValue)) {
+ /**
+ * If {@code returnedValue} is a {@link Restart} value, then {@code entry} will be reset, and the
+ * nodes specified by {@code returnedValue.getAdditionalKeysToRestart()} will be marked changed.
+ *
+ * @return {@code returnedValue instanceof Restart}
+ */
+ private boolean maybeHandleRestart(SkyKey key, NodeEntry entry, SkyValue returnedValue)
+ throws InterruptedException {
+ if (!(returnedValue instanceof Restart)) {
return false;
}
- evaluatorContext
- .getGraphInconsistencyReceiver()
- .noteInconsistencyAndMaybeThrow(key, /*otherKey=*/ null, Inconsistency.RESET_REQUESTED);
- entry.resetForRestartFromScratch();
+ restart(key, entry);
+
+ Restart restart = (Restart) returnedValue;
+
+ Map<SkyKey, ? extends NodeEntry> additionalNodesToRestart =
+ this.evaluatorContext
+ .getBatchValues(key, Reason.INVALIDATION, restart.getAdditionalKeysToRestart());
+ for (Entry<SkyKey, ? extends NodeEntry> restartEntry : additionalNodesToRestart.entrySet()) {
+ evaluatorContext
+ .getGraphInconsistencyReceiver()
+ .noteInconsistencyAndMaybeThrow(
+ restartEntry.getKey(),
+ /*otherKey=*/ key,
+ Inconsistency.CHILD_FORCED_REEVALUATION_BY_PARENT);
+ // Nodes are marked changed to ensure that they run. (Also, marking dirty-but-not-changed
+ // would fail if the node has no deps, because dirtying works only when nodes have deps.)
+ restartEntry.getValue().markDirty(/*isChanged=*/ true);
+ }
+
// TODO(mschaller): rdeps of children have to be handled here. If the graph does not keep edges,
// nothing has to be done, since there are no reverse deps to keep consistent. If the graph
// keeps edges, it's a harder problem. The reverse deps could just be removed, but in the case
@@ -670,6 +696,13 @@ public abstract class AbstractParallelEvaluator {
return true;
}
+ private void restart(SkyKey key, NodeEntry entry) {
+ evaluatorContext
+ .getGraphInconsistencyReceiver()
+ .noteInconsistencyAndMaybeThrow(key, /*otherKey=*/ null, Inconsistency.RESET_REQUESTED);
+ entry.resetForRestartFromScratch();
+ }
+
void propagateEvaluatorContextCrashIfAny() {
if (!evaluatorContext.getVisitor().getCrashes().isEmpty()) {
evaluatorContext