Copilot commented on code in PR #9282:
URL: https://github.com/apache/gravitino/pull/9282#discussion_r2587894164


##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    FilesetCatalogOperations filesetCatalogOperations = new 
FilesetCatalogOperations();
+
+    LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
+    when(localFileSystemProvider.scheme()).thenReturn("file");
+    when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))

Review Comment:
   Using `Mockito.any(Path.class)` and `Mockito.anyMap()` instead of the 
imported `any()` matcher is inconsistent. For consistency with the changes on 
lines 1462 and 1464 which use `any()`, these should also use `any()`:
   
   ```java
   when(localFileSystemProvider.getFileSystem(any(Path.class), anyMap()))
   ```
   ```suggestion
       when(localFileSystemProvider.getFileSystem(any(), any()))
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    FilesetCatalogOperations filesetCatalogOperations = new 
FilesetCatalogOperations();
+
+    LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
+    when(localFileSystemProvider.scheme()).thenReturn("file");
+    when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))
+        .thenAnswer(
+            invocation -> {
+              // Sleep 100s, however, the timeout is set to 6s by default in
+              // FilesetCatalogOperations, so
+              // it's expected to over within 10s
+              Thread.sleep(100000); // Simulate delay
+              return new LocalFileSystem();
+            });
+    Map<String, FileSystemProvider> fileSystemProviderMapOriginal = new 
HashMap<>();
+    fileSystemProviderMapOriginal.put("file", localFileSystemProvider);
+    FieldUtils.writeField(
+        filesetCatalogOperations, "fileSystemProvidersMap", 
fileSystemProviderMapOriginal, true);
+
+    FieldUtils.writeField(
+        filesetCatalogOperations, "propertiesMetadata", 
FILESET_PROPERTIES_METADATA, true);
+
+    // Test the following method should finish with 10s
+    long now = System.currentTimeMillis();
+    try {
+      filesetCatalogOperations.getFileSystem(new Path("file:///tmp"), 
ImmutableMap.of());
+    } catch (IOException e) {
+      Assertions.assertTrue(System.currentTimeMillis() - now <= 10000);
+    }
+  }

Review Comment:
   The test should call `filesetCatalogOperations.close()` to clean up the 
thread pool created in the test. Without this, the `fileSystemExecutor` threads 
will remain running after the test completes, potentially causing resource 
leaks or interference with other tests.
   
   Add cleanup after the assertion:
   ```java
   } finally {
     filesetCatalogOperations.close();
   }
   ```
   ```suggestion
       try {
         LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
         when(localFileSystemProvider.scheme()).thenReturn("file");
         when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))
             .thenAnswer(
                 invocation -> {
                   // Sleep 100s, however, the timeout is set to 6s by default 
in
                   // FilesetCatalogOperations, so
                   // it's expected to over within 10s
                   Thread.sleep(100000); // Simulate delay
                   return new LocalFileSystem();
                 });
         Map<String, FileSystemProvider> fileSystemProviderMapOriginal = new 
HashMap<>();
         fileSystemProviderMapOriginal.put("file", localFileSystemProvider);
         FieldUtils.writeField(
             filesetCatalogOperations, "fileSystemProvidersMap", 
fileSystemProviderMapOriginal, true);
   
         FieldUtils.writeField(
             filesetCatalogOperations, "propertiesMetadata", 
FILESET_PROPERTIES_METADATA, true);
   
         // Test the following method should finish with 10s
         long now = System.currentTimeMillis();
         try {
           filesetCatalogOperations.getFileSystem(new Path("file:///tmp"), 
ImmutableMap.of());
         } catch (IOException e) {
           Assertions.assertTrue(System.currentTimeMillis() - now <= 10000);
         }
       } finally {
         filesetCatalogOperations.close();
       }
   ```



##########
catalogs/catalog-fileset/src/main/java/org/apache/gravitino/catalog/fileset/FilesetCatalogOperations.java:
##########
@@ -994,6 +1014,8 @@ public void close() throws IOException {
       scheduler.shutdownNow();
     }
 
+    fileSystemExecutor.shutdownNow();

Review Comment:
   The `fileSystemExecutor.shutdownNow()` call should wait for termination and 
handle interruption of running tasks properly. Currently, it immediately shuts 
down without waiting, which could lead to tasks being interrupted abruptly.
   
   Consider adding:
   ```java
   fileSystemExecutor.shutdownNow();
   try {
     if (!fileSystemExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
       LOG.warn("FileSystem executor did not terminate in time");
     }
   } catch (InterruptedException e) {
     Thread.currentThread().interrupt();
     LOG.warn("Interrupted while waiting for executor shutdown", e);
   }
   ```
   
   This ensures a more graceful shutdown and proper handling of interrupted 
threads.
   ```suggestion
       fileSystemExecutor.shutdownNow();
       try {
         if (!fileSystemExecutor.awaitTermination(5, TimeUnit.SECONDS)) {
           LOG.warn("FileSystem executor did not terminate in time");
         }
       } catch (InterruptedException e) {
         Thread.currentThread().interrupt();
         LOG.warn("Interrupted while waiting for executor shutdown", e);
       }
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    FilesetCatalogOperations filesetCatalogOperations = new 
FilesetCatalogOperations();
+
+    LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
+    when(localFileSystemProvider.scheme()).thenReturn("file");
+    when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))
+        .thenAnswer(
+            invocation -> {
+              // Sleep 100s, however, the timeout is set to 6s by default in
+              // FilesetCatalogOperations, so
+              // it's expected to over within 10s

Review Comment:
   The comment states "it's expected to over within 10s" but should be "it's 
expected to be over within 10s".
   ```suggestion
                 // it's expected to be over within 10s
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {

Review Comment:
   [nitpick] The test name `testGetFileSystemWithTimeout` doesn't clearly 
indicate that it's testing a timeout failure scenario. Consider renaming to 
`testGetFileSystemTimeoutThrowsException` or `testGetFileSystemHandlesTimeout` 
to make the test intention clearer.
   ```suggestion
     void testGetFileSystemTimeoutThrowsException() throws Exception {
   ```



##########
catalogs/catalog-fileset/src/main/java/org/apache/gravitino/catalog/fileset/FilesetCatalogOperations.java:
##########
@@ -137,6 +140,23 @@ public class FilesetCatalogOperations extends 
ManagedSchemaOperations
   @VisibleForTesting ScheduledThreadPoolExecutor scheduler;
   @VisibleForTesting Cache<FileSystemCacheKey, FileSystem> fileSystemCache;
 
+  private final ThreadPoolExecutor fileSystemExecutor =
+      new ThreadPoolExecutor(
+          Math.max(2, Runtime.getRuntime().availableProcessors() * 2),
+          Math.max(2, Runtime.getRuntime().availableProcessors() * 2),
+          5L,
+          TimeUnit.SECONDS,
+          new ArrayBlockingQueue<>(1000),
+          new ThreadFactoryBuilder()
+              .setDaemon(true)
+              .setNameFormat("fileset-filesystem-getter-pool-%d")
+              .build(),
+          new ThreadPoolExecutor.AbortPolicy()) {
+        {
+          allowCoreThreadTimeOut(true);
+        }
+      };

Review Comment:
   The `fileSystemExecutor` ThreadPoolExecutor is initialized as a final field 
during class construction. This means it's created immediately when the class 
is instantiated, even before `initialize()` is called. This can lead to 
resource leaks if the class is instantiated but never properly initialized or 
closed.
   
   Consider making this a lazy-initialized field that is created in the 
`initialize()` method, similar to how `scheduler` is handled. This ensures 
proper lifecycle management and prevents creating thread pools for objects that 
may not be fully initialized.



##########
bundles/aws/src/main/java/org/apache/gravitino/s3/fs/S3FileSystemProvider.java:
##########
@@ -129,6 +131,33 @@ private void checkAndSetCredentialProvider(Map<String, 
String> configs) {
     }
   }
 

Review Comment:
   The `additionalS3Config` method lacks proper documentation. Since this 
method modifies configuration with performance-impacting defaults, it should 
have a Javadoc explaining the purpose and impact, similar to the other 
filesystem providers.
   
   Add Javadoc:
   ```java
   /**
    * Adds additional S3 configuration defaults to speed up failure detection.
    * These configurations reduce retry attempts and timeouts to prevent long 
hangs
    * when the S3 service is unreachable.
    *
    * @param configs The original configuration map
    * @return A new immutable map with additional configurations
    */
   private Map<String, String> additionalS3Config(Map<String, String> configs) {
   ```
   ```suggestion
   
     /**
      * Adds additional S3 configuration defaults to speed up failure detection.
      * <p>
      * These configurations reduce retry attempts and timeouts to prevent long 
hangs
      * when the S3 service is unreachable. This is especially useful in test 
cases
      * and environments where fast failure is preferred over long retry cycles.
      * <p>
      * The following defaults are set if not already present:
      * <ul>
      *   <li>fs.s3a.attempts.maximum = 2</li>
      *   <li>fs.s3a.connection.establish.timeout = 5000</li>
      *   <li>fs.s3a.retry.limit = 2</li>
      *   <li>fs.s3a.retry.throttle.limit = 2</li>
      * </ul>
      *
      * @param configs The original configuration map
      * @return A new immutable map with additional configurations
      */
   ```



##########
bundles/azure/src/main/java/org/apache/gravitino/abs/fs/AzureFileSystemProvider.java:
##########
@@ -101,6 +103,19 @@ public Map<String, String> 
getFileSystemCredentialConf(Credential[] credentials)
     return result;
   }
 

Review Comment:
   The `additionalAzureConfig` method lacks proper documentation. Since this 
method modifies configuration with performance-impacting defaults, it should 
have a Javadoc explaining the purpose and impact, similar to the other 
filesystem providers.
   
   Add Javadoc:
   ```java
   /**
    * Adds additional Azure configuration defaults to speed up failure 
detection.
    * These configurations reduce retry attempts to prevent long hangs
    * when the Azure service is unreachable.
    *
    * @param configs The original configuration map
    * @return A new immutable map with additional configurations
    */
   private Map<String, String> additionalAzureConfig(Map<String, String> 
configs) {
   ```
   ```suggestion
   
     /**
      * Adds additional Azure configuration defaults to speed up failure 
detection.
      * These configurations reduce retry attempts to prevent long hangs
      * when the Azure service is unreachable.
      *
      * @param configs The original configuration map
      * @return A new immutable map with additional configurations
      */
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    FilesetCatalogOperations filesetCatalogOperations = new 
FilesetCatalogOperations();
+
+    LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
+    when(localFileSystemProvider.scheme()).thenReturn("file");
+    when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))
+        .thenAnswer(
+            invocation -> {
+              // Sleep 100s, however, the timeout is set to 6s by default in
+              // FilesetCatalogOperations, so
+              // it's expected to over within 10s
+              Thread.sleep(100000); // Simulate delay
+              return new LocalFileSystem();
+            });
+    Map<String, FileSystemProvider> fileSystemProviderMapOriginal = new 
HashMap<>();
+    fileSystemProviderMapOriginal.put("file", localFileSystemProvider);
+    FieldUtils.writeField(
+        filesetCatalogOperations, "fileSystemProvidersMap", 
fileSystemProviderMapOriginal, true);

Review Comment:
   [nitpick] The variable name `fileSystemProviderMapOriginal` suggests it's 
the original map, but it's actually a newly created map for testing purposes. 
Consider renaming to `testFileSystemProviderMap` or `mockFileSystemProviderMap` 
for clarity.
   ```suggestion
       Map<String, FileSystemProvider> testFileSystemProviderMap = new 
HashMap<>();
       testFileSystemProviderMap.put("file", localFileSystemProvider);
       FieldUtils.writeField(
           filesetCatalogOperations, "fileSystemProvidersMap", 
testFileSystemProviderMap, true);
   ```



##########
bundles/gcp/src/main/java/org/apache/gravitino/gcs/fs/GCSFileSystemProvider.java:
##########
@@ -62,6 +64,25 @@ public Map<String, String> 
getFileSystemCredentialConf(Credential[] credentials)
     return result;
   }
 

Review Comment:
   The `additionalGCSConfig` method lacks proper documentation. Since this 
method modifies configuration with performance-impacting defaults, it should 
have a Javadoc explaining the purpose and impact, similar to the other 
filesystem providers.
   
   Add Javadoc:
   ```java
   /**
    * Adds additional GCS configuration defaults to speed up failure detection.
    * These configurations reduce retry attempts and timeouts to prevent long 
hangs
    * when the GCS service is unreachable.
    *
    * @param configs The original configuration map
    * @return A new immutable map with additional configurations
    */
   private Map<String, String> additionalGCSConfig(Map<String, String> configs) 
{
   ```
   ```suggestion
   
     /**
      * Adds additional GCS configuration defaults to speed up failure 
detection.
      * These configurations reduce retry attempts and timeouts to prevent long 
hangs
      * when the GCS service is unreachable.
      *
      * @param configs The original configuration map
      * @return A new immutable map with additional configurations
      */
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1872,41 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  void testGetFileSystemWithTimeout() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    FilesetCatalogOperations filesetCatalogOperations = new 
FilesetCatalogOperations();
+
+    LocalFileSystemProvider localFileSystemProvider = 
Mockito.mock(LocalFileSystemProvider.class);
+    when(localFileSystemProvider.scheme()).thenReturn("file");
+    when(localFileSystemProvider.getFileSystem(Mockito.any(Path.class), 
Mockito.anyMap()))
+        .thenAnswer(
+            invocation -> {
+              // Sleep 100s, however, the timeout is set to 6s by default in
+              // FilesetCatalogOperations, so
+              // it's expected to over within 10s
+              Thread.sleep(100000); // Simulate delay
+              return new LocalFileSystem();
+            });
+    Map<String, FileSystemProvider> fileSystemProviderMapOriginal = new 
HashMap<>();
+    fileSystemProviderMapOriginal.put("file", localFileSystemProvider);
+    FieldUtils.writeField(
+        filesetCatalogOperations, "fileSystemProvidersMap", 
fileSystemProviderMapOriginal, true);
+
+    FieldUtils.writeField(
+        filesetCatalogOperations, "propertiesMetadata", 
FILESET_PROPERTIES_METADATA, true);
+
+    // Test the following method should finish with 10s
+    long now = System.currentTimeMillis();
+    try {
+      filesetCatalogOperations.getFileSystem(new Path("file:///tmp"), 
ImmutableMap.of());
+    } catch (IOException e) {
+      Assertions.assertTrue(System.currentTimeMillis() - now <= 10000);
+    }

Review Comment:
   The timeout assertion logic is incorrect. If no exception is thrown (which 
would be a bug), this test would pass incorrectly. The assertion should be 
outside the catch block to ensure the method actually throws an exception.
   
   Refactor to:
   ```java
   long now = System.currentTimeMillis();
   IOException exception = Assertions.assertThrows(
       IOException.class,
       () -> filesetCatalogOperations.getFileSystem(new Path("file:///tmp"), 
ImmutableMap.of()));
   Assertions.assertTrue(System.currentTimeMillis() - now <= 10000);
   ```
   
   This ensures that an IOException is thrown and the timeout is enforced 
correctly.
   ```suggestion
       IOException exception = Assertions.assertThrows(
           IOException.class,
           () -> filesetCatalogOperations.getFileSystem(new 
Path("file:///tmp"), ImmutableMap.of()));
       Assertions.assertTrue(System.currentTimeMillis() - now <= 10000);
   ```



##########
catalogs/hadoop-common/src/main/java/org/apache/gravitino/catalog/hadoop/fs/HDFSFileSystemProvider.java:
##########
@@ -44,6 +48,25 @@ public String scheme() {
     return SCHEME_HDFS;
   }
 
+  private Map<String, String> additionalHDFSConfig(Map<String, String> 
configs) {
+    Map<String, String> additionalConfigs = Maps.newHashMap(configs);
+
+    // Avoid multiple retries to speed up failure in test cases.
+    // Use hard code instead of 
CommonConfigurationKeysPublic.IPC_CLIENT_CONNECT_TIMEOUT_KEY to
+    // avoid dependency on a specific Hadoop version.
+    if (!configs.containsKey("ipc.client.connect.timeout")) {
+      additionalConfigs.put("ipc.client.connect.timeout", "5000");

Review Comment:
   [nitpick] The hardcoded timeout value of 5000ms should be documented or made 
a constant. This magic number appears across multiple filesystem providers 
(HDFS, GCS, S3, Azure, OSS) with the same value. Consider extracting this to a 
shared constant for consistency and maintainability.
   
   For example:
   ```java
   private static final String DEFAULT_CONNECTION_TIMEOUT = "5000";
   ```
   
   This would make it easier to adjust these values globally if needed and 
makes the intent clearer.



##########
catalogs/hadoop-common/src/main/java/org/apache/gravitino/catalog/hadoop/fs/HDFSFileSystemProvider.java:
##########
@@ -44,6 +48,25 @@ public String scheme() {
     return SCHEME_HDFS;
   }
 

Review Comment:
   The `additionalHDFSConfig` method lacks proper documentation. Since this 
method modifies configuration with performance-impacting defaults, it should 
have a Javadoc explaining:
   - The purpose of adding these configurations
   - Why these specific defaults are chosen
   - The impact on behavior (faster failures in test cases)
   
   Example:
   ```java
   /**
    * Adds additional HDFS configuration defaults to speed up failure detection.
    * These configurations reduce retry attempts and timeouts to prevent long 
hangs
    * when the HDFS service is unreachable.
    *
    * @param configs The original configuration map
    * @return A new immutable map with additional configurations
    */
   private Map<String, String> additionalHDFSConfig(Map<String, String> 
configs) {
   ```
   ```suggestion
   
     /**
      * Adds additional HDFS configuration defaults to speed up failure 
detection.
      * <p>
      * These configurations reduce retry attempts and timeouts to prevent long 
hangs
      * when the HDFS service is unreachable, especially in test cases. 
Hardcoded keys
      * are used instead of Hadoop constants to avoid dependency on a specific 
Hadoop version.
      * <ul>
      *   <li>ipc.client.connect.timeout: Set to 5000ms if not present, to 
reduce connection wait time.</li>
      *   <li>ipc.client.ping: Set to true if not present, to enable client 
pinging.</li>
      * </ul>
      *
      * @param configs The original configuration map
      * @return A new immutable map with additional configurations for faster 
failure detection
      */
   ```



##########
catalogs/catalog-fileset/src/main/java/org/apache/gravitino/catalog/fileset/FilesetCatalogOperations.java:
##########
@@ -137,6 +140,23 @@ public class FilesetCatalogOperations extends 
ManagedSchemaOperations
   @VisibleForTesting ScheduledThreadPoolExecutor scheduler;
   @VisibleForTesting Cache<FileSystemCacheKey, FileSystem> fileSystemCache;
 
+  private final ThreadPoolExecutor fileSystemExecutor =
+      new ThreadPoolExecutor(
+          Math.max(2, Runtime.getRuntime().availableProcessors() * 2),
+          Math.max(2, Runtime.getRuntime().availableProcessors() * 2),
+          5L,
+          TimeUnit.SECONDS,
+          new ArrayBlockingQueue<>(1000),
+          new ThreadFactoryBuilder()
+              .setDaemon(true)
+              .setNameFormat("fileset-filesystem-getter-pool-%d")
+              .build(),
+          new ThreadPoolExecutor.AbortPolicy()) {
+        {
+          allowCoreThreadTimeOut(true);
+        }
+      };

Review Comment:
   [nitpick] The ThreadPoolExecutor is configured with a fixed core and maximum 
pool size (both set to `availableProcessors() * 2`), combined with 
`allowCoreThreadTimeOut(true)`. This means all threads can timeout and be 
terminated, which could cause thread creation overhead on every FileSystem 
retrieval operation.
   
   Consider either:
   1. Keep a minimum number of core threads alive (e.g., 1-2) by not allowing 
core thread timeout
   2. Or increase the keep-alive time from 5 seconds to reduce frequent thread 
creation/destruction
   
   For example:
   ```java
   Math.max(2, Runtime.getRuntime().availableProcessors()),  // corePoolSize
   Math.max(2, Runtime.getRuntime().availableProcessors() * 2),  // 
maximumPoolSize
   60L,  // increased keepAliveTime
   TimeUnit.SECONDS,
   ```
   
   This would maintain a more stable thread pool for better performance.
   ```suggestion
             Math.max(2, Runtime.getRuntime().availableProcessors()), // 
corePoolSize
             Math.max(2, Runtime.getRuntime().availableProcessors() * 2), // 
maximumPoolSize
             60L, // increased keepAliveTime
             TimeUnit.SECONDS,
             new ArrayBlockingQueue<>(1000),
             new ThreadFactoryBuilder()
                 .setDaemon(true)
                 .setNameFormat("fileset-filesystem-getter-pool-%d")
                 .build(),
             new ThreadPoolExecutor.AbortPolicy());
   ```



##########
catalogs/catalog-fileset/src/main/java/org/apache/gravitino/catalog/fileset/FilesetCatalogOperations.java:
##########
@@ -1395,30 +1417,43 @@ FileSystem getFileSystem(Path path, Map<String, String> 
config) throws IOExcepti
                 .catalogPropertiesMetadata()
                 .getOrDefault(
                     config, 
FilesetCatalogPropertiesMetadata.FILESYSTEM_CONNECTION_TIMEOUT_SECONDS);
+
+    Future<FileSystem> fileSystemFuture =
+        fileSystemExecutor.submit(() -> provider.getFileSystem(path, config));
+
     try {
-      AtomicReference<FileSystem> fileSystem = new AtomicReference<>();
-      Awaitility.await()
-          .atMost(timeoutSeconds, TimeUnit.SECONDS)
-          .pollInterval(1, TimeUnit.MILLISECONDS)
-          .until(
-              () -> {
-                fileSystem.set(provider.getFileSystem(path, config));
-                return true;
-              });
-      return fileSystem.get();
-    } catch (ConditionTimeoutException e) {
+      return fileSystemFuture.get(timeoutSeconds, TimeUnit.SECONDS);
+    } catch (TimeoutException e) {
+      fileSystemFuture.cancel(true);
+
+      LOG.warn(
+          "Timeout when getting FileSystem for path: {}, scheme: {}, provider: 
{} within {} seconds",
+          path,
+          scheme,
+          provider,
+          timeoutSeconds,
+          e);
+
       throw new IOException(
           String.format(
-              "Failed to get FileSystem for path: %s, scheme: %s, provider: 
%s, config: %s within %s "
+              "Failed to get FileSystem for path: %s, scheme: %s, provider: 
%s, within %s "

Review Comment:
   The error message on line 1439 has an extra comma after "provider: %s," 
which results in awkward formatting like "provider: XYZ, within". Remove the 
comma:
   
   ```java
   "Failed to get FileSystem for path: %s, scheme: %s, provider: %s within %s "
   ```
   ```suggestion
                 "Failed to get FileSystem for path: %s, scheme: %s, provider: 
%s within %s "
   ```



##########
bundles/aliyun/src/main/java/org/apache/gravitino/oss/fs/OSSFileSystemProvider.java:
##########
@@ -80,6 +82,25 @@ public Map<String, String> 
getFileSystemCredentialConf(Credential[] credentials)
     return result;
   }
 

Review Comment:
   The `additionalOSSConfig` method lacks proper documentation. Since this 
method modifies configuration with performance-impacting defaults, it should 
have a Javadoc explaining the purpose and impact, similar to the other 
filesystem providers.
   
   Add Javadoc:
   ```java
   /**
    * Adds additional OSS configuration defaults to speed up failure detection.
    * These configurations reduce retry attempts and timeouts to prevent long 
hangs
    * when the OSS service is unreachable.
    *
    * @param configs The original configuration map
    * @return A new immutable map with additional configurations
    */
   private Map<String, String> additionalOSSConfig(Map<String, String> configs) 
{
   ```
   ```suggestion
   
     /**
      * Adds additional OSS configuration defaults to speed up failure 
detection.
      * These configurations reduce retry attempts and timeouts to prevent long 
hangs
      * when the OSS service is unreachable. This is especially useful in test 
cases
      * and environments where quick failure is preferred over long retries.
      *
      * @param configs The original configuration map
      * @return A new immutable map with additional configurations for OSS
      */
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to