Allow ParallelEvaluator to not store errors alongside values if nodes recover from errors. In the case of a single keep_going build, with no subsequent nokeep_going builds, storing the errors is unnecessary.

--
MOS_MIGRATED_REVID=114355846
diff --git a/src/test/java/com/google/devtools/build/skyframe/ChainedFunction.java b/src/test/java/com/google/devtools/build/skyframe/ChainedFunction.java
index a370cdc..fd2f44b 100644
--- a/src/test/java/com/google/devtools/build/skyframe/ChainedFunction.java
+++ b/src/test/java/com/google/devtools/build/skyframe/ChainedFunction.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.skyframe;
 
+import com.google.common.collect.ImmutableList;
 import com.google.devtools.build.lib.util.Preconditions;
 import com.google.devtools.build.skyframe.GraphTester.ValueComputer;
 import com.google.devtools.build.skyframe.ParallelEvaluator.SkyFunctionEnvironment;
@@ -26,7 +27,7 @@
  * {@link ValueComputer} that can be chained together with others of its type to synchronize the
  * order in which builders finish.
  */
-final class ChainedFunction implements SkyFunction {
+public final class ChainedFunction implements SkyFunction {
   @Nullable private final SkyValue value;
   @Nullable private final CountDownLatch notifyStart;
   @Nullable private final CountDownLatch waitToFinish;
@@ -34,9 +35,14 @@
   private final boolean waitForException;
   private final Iterable<SkyKey> deps;
 
-  ChainedFunction(@Nullable CountDownLatch notifyStart, @Nullable CountDownLatch waitToFinish,
-      @Nullable CountDownLatch notifyFinish, boolean waitForException,
-      @Nullable SkyValue value, Iterable<SkyKey> deps) {
+  /** Do not use! Use {@link Builder} instead. */
+  ChainedFunction(
+      @Nullable CountDownLatch notifyStart,
+      @Nullable CountDownLatch waitToFinish,
+      @Nullable CountDownLatch notifyFinish,
+      boolean waitForException,
+      @Nullable SkyValue value,
+      Iterable<SkyKey> deps) {
     this.notifyStart = notifyStart;
     this.waitToFinish = waitToFinish;
     this.notifyFinish = notifyFinish;
@@ -80,6 +86,51 @@
     }
   }
 
+  /** Builder for {@link ChainedFunction} objects. */
+  public static class Builder {
+    @Nullable private SkyValue value;
+    @Nullable private CountDownLatch notifyStart;
+    @Nullable private CountDownLatch waitToFinish;
+    @Nullable private CountDownLatch notifyFinish;
+    private boolean waitForException;
+    private Iterable<SkyKey> deps = ImmutableList.of();
+
+    public Builder setValue(SkyValue value) {
+      this.value = value;
+      return this;
+    }
+
+    public Builder setNotifyStart(CountDownLatch notifyStart) {
+      this.notifyStart = notifyStart;
+      return this;
+    }
+
+    public Builder setWaitToFinish(CountDownLatch waitToFinish) {
+      this.waitToFinish = waitToFinish;
+      return this;
+    }
+
+    public Builder setNotifyFinish(CountDownLatch notifyFinish) {
+      this.notifyFinish = notifyFinish;
+      return this;
+    }
+
+    public Builder setWaitForException(boolean waitForException) {
+      this.waitForException = waitForException;
+      return this;
+    }
+
+    public Builder setDeps(Iterable<SkyKey> deps) {
+      this.deps = Preconditions.checkNotNull(deps);
+      return this;
+    }
+
+    public SkyFunction build() {
+      return new ChainedFunction(
+          notifyStart, waitToFinish, notifyFinish, waitForException, value, deps);
+    }
+  }
+
   @Override
   public String extractTag(SkyKey skyKey) {
     throw new UnsupportedOperationException();