Permit serialization arising from ErrorInfo#encode to wait on a future. This
prevents Bazel from crashing on an ErrorInfo with an exception from
ActionExecutionFunction, which can contain an action, and therefore contain a
NestedSet.
package com.google.devtools.build.lib.skyframe.serialization;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.MoreExecutors;
import com.google.protobuf.ByteString;
import javax.annotation.Nullable;
@@ -42,6 +44,13 @@ public abstract class SerializationResult<T> {
*/
public abstract <S> SerializationResult<S> with(S newObj);
+ /**
+ * Returns a new {@link SerializationResult} with the same object but with a new future that waits
+ * on the given future as well as the current future.
+ */
+ public abstract SerializationResult<T> withAdditionalFuture(
+ ListenableFuture<Void> additionalFuture);
+
/**
* Returns a {@link ListenableFuture} that, if not null, must complete successfully before {@link
* #getObject} can be written remotely.
@@ -76,6 +85,11 @@ public abstract class SerializationResult<T> {
return new ObjectWithoutFuture<>(newObj);
}
+ @Override
+ public SerializationResult<T> withAdditionalFuture(ListenableFuture<Void> additionalFuture) {
+ return new ObjectWithFuture<>(getObject(), additionalFuture);
+ }
+
@Override
public ListenableFuture<Void> getFutureToBlockWritesOn() {
return null;
@@ -95,6 +109,14 @@ public abstract class SerializationResult<T> {
return new ObjectWithFuture<>(newObj, futureToBlockWritesOn);
}
+ @Override
+ public SerializationResult<T> withAdditionalFuture(ListenableFuture<Void> additionalFuture) {
+ ListenableFuture<Void> combinedFuture =
+ Futures.whenAllComplete(additionalFuture, futureToBlockWritesOn)
+ .call(() -> null, MoreExecutors.directExecutor());
+ return new ObjectWithFuture<>(getObject(), combinedFuture);
+ }
+
@Override
public ListenableFuture<Void> getFutureToBlockWritesOn() {
return futureToBlockWritesOn;
