getFromFuture will cancel the future by default on InterruptedException
Fixes #11339.
Closes #12453.
PiperOrigin-RevId: 341993215
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java
index 7f3f83d..93ec205 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteActionInputFetcher.java
@@ -34,6 +34,7 @@
import com.google.devtools.build.lib.remote.common.CacheNotFoundException;
import com.google.devtools.build.lib.remote.util.DigestUtil;
import com.google.devtools.build.lib.remote.util.TracingMetadataUtils;
+import com.google.devtools.build.lib.remote.util.Utils;
import com.google.devtools.build.lib.sandbox.SandboxHelpers;
import com.google.devtools.build.lib.vfs.Path;
import io.grpc.Context;
@@ -42,7 +43,6 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ExecutionException;
import javax.annotation.concurrent.GuardedBy;
/**
@@ -145,14 +145,7 @@
void downloadFile(Path path, FileArtifactValue metadata)
throws IOException, InterruptedException {
- try {
- downloadFileAsync(path, metadata).get();
- } catch (ExecutionException e) {
- if (e.getCause() instanceof IOException) {
- throw (IOException) e.getCause();
- }
- throw new IOException(e.getCause());
- }
+ Utils.getFromFuture(downloadFileAsync(path, metadata));
}
private ListenableFuture<Void> downloadFileAsync(Path path, FileArtifactValue metadata)
diff --git a/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java b/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
index 511c5bd..5fc3b3a 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/RemoteCache.java
@@ -218,7 +218,7 @@
try {
if (interruptedException == null) {
// Wait for all transfers to finish.
- getFromFuture(transfer);
+ getFromFuture(transfer, cancelRemainingOnInterrupt);
} else {
transfer.cancel(true);
}
diff --git a/src/main/java/com/google/devtools/build/lib/remote/util/Utils.java b/src/main/java/com/google/devtools/build/lib/remote/util/Utils.java
index 9d07d7a..86f21a5 100644
--- a/src/main/java/com/google/devtools/build/lib/remote/util/Utils.java
+++ b/src/main/java/com/google/devtools/build/lib/remote/util/Utils.java
@@ -57,9 +57,22 @@
/**
* Returns the result of a {@link ListenableFuture} if successful, or throws any checked {@link
* Exception} directly if it's an {@link IOException} or else wraps it in an {@link IOException}.
+ *
+ * <p>Cancel the future on {@link InterruptedException}
*/
public static <T> T getFromFuture(ListenableFuture<T> f)
throws IOException, InterruptedException {
+ return getFromFuture(f, /* cancelOnInterrupt */ true);
+ }
+
+ /**
+ * Returns the result of a {@link ListenableFuture} if successful, or throws any checked {@link
+ * Exception} directly if it's an {@link IOException} or else wraps it in an {@link IOException}.
+ *
+ * @param cancelOnInterrupt cancel the future on {@link InterruptedException} if {@code true}.
+ */
+ public static <T> T getFromFuture(ListenableFuture<T> f, boolean cancelOnInterrupt)
+ throws IOException, InterruptedException {
try {
return f.get();
} catch (ExecutionException e) {
@@ -74,6 +87,11 @@
throw (RuntimeException) cause;
}
throw new IOException(cause);
+ } catch (InterruptedException e) {
+ if (cancelOnInterrupt) {
+ f.cancel(true);
+ }
+ throw e;
}
}