aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/skyframe
diff options
context:
space:
mode:
authorGravatar Janak Ramakrishnan <janakr@google.com>2016-08-10 22:23:57 +0000
committerGravatar Yue Gan <yueg@google.com>2016-08-11 09:17:41 +0000
commitfb1d53df557ee10f13ed4299f0688ea81cfe4fb6 (patch)
tree7e0e4554f4c0a1e6d033a9e7cf204c9ec00d5d64 /src/main/java/com/google/devtools/build/skyframe
parent9e71a5b2b90c14ca7b097930e8dff3fafad86407 (diff)
Fix bug in ParallelEvaluator when an error dep was not newly requested in a nokeep_going build because it finished building in between the time it was first requested and when we checked it for done-ness after the SkyFunction evaluation.
This results in an IllegalStateException that gets ignored (and, importantly, not propagated) by AbstractQueueVisitor because AbstractQueueVisitor only records and propagates the first Throwable encountered. For nokeep_going evaluations, this will be the SchedulerException that we use for control flow. The IllegalStateException in question is benign in this case because it's merely from a Preconditions failure and doesn't leave anything in a bad state. It's possible, though, that we have other bugs that are being masked in this way. -- MOS_MIGRATED_REVID=129919336
Diffstat (limited to 'src/main/java/com/google/devtools/build/skyframe')
-rw-r--r--src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java42
1 files changed, 18 insertions, 24 deletions
diff --git a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
index ea83d875cc..2bbf62d175 100644
--- a/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
+++ b/src/main/java/com/google/devtools/build/skyframe/ParallelEvaluator.java
@@ -51,7 +51,6 @@ import com.google.devtools.build.skyframe.NodeEntry.DependencyState;
import com.google.devtools.build.skyframe.NodeEntry.DirtyState;
import com.google.devtools.build.skyframe.QueryableGraph.Reason;
import com.google.devtools.build.skyframe.SkyFunctionException.ReifiedSkyFunctionException;
-
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
@@ -70,7 +69,6 @@ import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Logger;
-
import javax.annotation.Nullable;
/**
@@ -1125,29 +1123,25 @@ public final class ParallelEvaluator implements Evaluator {
skyKey,
state,
childErrorKey);
- Preconditions.checkState(
- !state.getTemporaryDirectDeps().expensiveContains(childErrorKey),
- "Done error was already known: %s %s %s %s",
- skyKey,
- state,
- childErrorKey,
- childErrorEntry);
- Preconditions.checkState(
- newDirectDeps.contains(childErrorKey), "%s %s %s", state, childErrorKey, newDirectDeps);
- state.addTemporaryDirectDeps(GroupedListHelper.create(ImmutableList.of(childErrorKey)));
- DependencyState childErrorState;
- if (oldDeps.contains(childErrorKey)) {
- childErrorState = childErrorEntry.checkIfDoneForDirtyReverseDep(skyKey);
- } else {
- childErrorState = childErrorEntry.addReverseDepAndCheckIfDone(skyKey);
+ if (newDirectDeps.contains(childErrorKey)) {
+ // Add this dep if it was just requested. In certain rare race conditions (see
+ // MemoizingEvaluatorTest.cachedErrorCausesRestart) this dep may have already been
+ // requested.
+ state.addTemporaryDirectDeps(GroupedListHelper.create(ImmutableList.of(childErrorKey)));
+ DependencyState childErrorState;
+ if (oldDeps.contains(childErrorKey)) {
+ childErrorState = childErrorEntry.checkIfDoneForDirtyReverseDep(skyKey);
+ } else {
+ childErrorState = childErrorEntry.addReverseDepAndCheckIfDone(skyKey);
+ }
+ Preconditions.checkState(
+ childErrorState == DependencyState.DONE,
+ "skyKey: %s, state: %s childErrorKey: %s",
+ skyKey,
+ state,
+ childErrorKey,
+ childErrorEntry);
}
- Preconditions.checkState(
- childErrorState == DependencyState.DONE,
- "skyKey: %s, state: %s childErrorKey: %s",
- skyKey,
- state,
- childErrorKey,
- childErrorEntry);
ErrorInfo childErrorInfo = Preconditions.checkNotNull(childErrorEntry.getErrorInfo());
visitor.preventNewEvaluations();
throw SchedulerException.ofError(childErrorInfo, childErrorKey);