Support interruption in decompression

Decompressing large archives can take a while. Therefore, properly
honor interruption requests.

Improves on #8346.

Change-Id: I648bd1dc4b9e1f4b03065ffff3d9d66cd9cc92a1
PiperOrigin-RevId: 249246136
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunction.java
index 6c29464..180119d 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunction.java
@@ -39,7 +39,11 @@
       throws IOException;
 
   @Override
-  public Path decompress(DecompressorDescriptor descriptor) throws IOException {
+  public Path decompress(DecompressorDescriptor descriptor)
+      throws InterruptedException, IOException {
+    if (Thread.interrupted()) {
+      throw new InterruptedException();
+    }
     Optional<String> prefix = descriptor.prefix();
     boolean foundPrefix = false;
     Set<String> availablePrefixes = new HashSet<>();
@@ -92,6 +96,9 @@
             filename.setLastModifiedTime(lastModified.getTime());
           }
         }
+        if (Thread.interrupted()) {
+          throw new InterruptedException();
+        }
       }
 
       if (prefix.isPresent() && !foundPrefix) {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
index de0bea3..f219206 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/DecompressorValue.java
@@ -71,7 +71,7 @@
     }
 
     Path decompress(DecompressorDescriptor descriptor)
-        throws IOException, RepositoryFunctionException;
+        throws IOException, RepositoryFunctionException, InterruptedException;
   }
 
   private final Path directory;
@@ -121,7 +121,7 @@
   }
 
   public static Path decompress(DecompressorDescriptor descriptor)
-      throws RepositoryFunctionException {
+      throws RepositoryFunctionException, InterruptedException {
     try {
       return descriptor.getDecompressor().decompress(descriptor);
     } catch (IOException e) {
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
index d046523..b986331 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressor.java
@@ -74,7 +74,8 @@
    */
   @Override
   @Nullable
-  public Path decompress(DecompressorDescriptor descriptor) throws IOException {
+  public Path decompress(DecompressorDescriptor descriptor)
+      throws IOException, InterruptedException {
     Path destinationDirectory = descriptor.repositoryPath();
     Optional<String> prefix = descriptor.prefix();
     boolean foundPrefix = false;
@@ -122,7 +123,7 @@
       PathFragment strippedRelativePath,
       Optional<String> prefix,
       Map<Path, PathFragment> symlinks)
-      throws IOException {
+      throws IOException, InterruptedException {
     if (strippedRelativePath.isAbsolute()) {
       throw new IOException(
           String.format(
@@ -156,6 +157,9 @@
       try (InputStream input = reader.getInputStream(entry);
           OutputStream output = outputPath.getOutputStream()) {
         ByteStreams.copy(input, output);
+        if (Thread.interrupted()) {
+          throw new InterruptedException();
+        }
       }
       outputPath.chmod(permissions);
       outputPath.setLastModifiedTime(entry.getTime());
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunctionTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunctionTest.java
index debcb14..2853136 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/CompressedTarFunctionTest.java
@@ -17,7 +17,6 @@
 import static com.google.devtools.build.lib.bazel.repository.TestArchiveDescriptor.INNER_FOLDER_NAME;
 import static com.google.devtools.build.lib.bazel.repository.TestArchiveDescriptor.ROOT_FOLDER_NAME;
 
-import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
 import com.google.devtools.build.lib.vfs.Path;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -65,8 +64,7 @@
     archiveDescriptor.assertOutputFiles(outputDir, INNER_FOLDER_NAME);
   }
 
-  private Path decompress(DecompressorDescriptor.Builder descriptorBuilder)
-      throws IOException, RepositoryFunctionException {
+  private Path decompress(DecompressorDescriptor.Builder descriptorBuilder) throws Exception {
     descriptorBuilder.setDecompressor(TarGzFunction.INSTANCE);
     return new CompressedTarFunction() {
       @Override
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java
index 7a4c3f8..0ba47de 100644
--- a/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/ZipDecompressorTest.java
@@ -18,9 +18,7 @@
 import static com.google.devtools.build.lib.bazel.repository.TestArchiveDescriptor.INNER_FOLDER_NAME;
 import static com.google.devtools.build.lib.bazel.repository.TestArchiveDescriptor.ROOT_FOLDER_NAME;
 
-import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
 import com.google.devtools.build.lib.vfs.Path;
-import java.io.IOException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -70,8 +68,7 @@
     archiveDescriptor.assertOutputFiles(outputDir, INNER_FOLDER_NAME);
   }
 
-  private Path decompress(DecompressorDescriptor.Builder descriptorBuilder)
-      throws IOException, RepositoryFunctionException {
+  private Path decompress(DecompressorDescriptor.Builder descriptorBuilder) throws Exception {
     descriptorBuilder.setDecompressor(ZipDecompressor.INSTANCE);
     return ZipDecompressor.INSTANCE.decompress(descriptorBuilder.build());
   }
diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/BazelEmbeddedSkylarkBlackBoxTest.java b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/BazelEmbeddedSkylarkBlackBoxTest.java
index 16e6193..04101f5c 100644
--- a/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/BazelEmbeddedSkylarkBlackBoxTest.java
+++ b/src/test/java/com/google/devtools/build/lib/blackbox/tests/workspace/BazelEmbeddedSkylarkBlackBoxTest.java
@@ -21,11 +21,9 @@
 import com.google.devtools.build.lib.blackbox.framework.BuilderRunner;
 import com.google.devtools.build.lib.blackbox.framework.PathUtils;
 import com.google.devtools.build.lib.blackbox.junit.AbstractBlackBoxTest;
-import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
 import com.google.devtools.build.lib.vfs.FileSystem;
 import com.google.devtools.build.lib.vfs.util.FileSystems;
 import java.io.File;
-import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -134,7 +132,7 @@
     }
   }
 
-  private Path decompress(Path dataTarPath) throws IOException, RepositoryFunctionException {
+  private Path decompress(Path dataTarPath) throws Exception {
     FileSystem fs = FileSystems.getNativeFileSystem();
     com.google.devtools.build.lib.vfs.Path dataTarPathForDecompress =
         fs.getPath(dataTarPath.toAbsolutePath().toString());