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


##########
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, Math.min(Runtime.getRuntime().availableProcessors() * 2, 
16)),
+          Math.max(2, Math.min(Runtime.getRuntime().availableProcessors() * 2, 
32)),
+          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 ThreadPoolExecutor is initialized as a final instance field, but the 
`close()` method calls `shutdownNow()` without checking if it has already been 
shut down. If `close()` is called multiple times, this could throw an exception 
or cause issues. Consider adding a guard to check the executor's state before 
shutting it down, or use a safer shutdown pattern.



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1874,42 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  @Timeout(15)
+  void testGetFileSystemTimeoutThrowsException() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    try (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 -> {
+                // Block 100s, however, the timeout is set to 6s by default in
+                // FilesetCatalogOperations, so it's expected to be over 
within 10s
+                Awaitility.await().forever().until(() -> false);
+                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) {
+        long timeTake = System.currentTimeMillis() - now;
+        Assertions.assertTrue(timeTake <= 10000);
+      }

Review Comment:
   The test expects an IOException to be thrown but doesn't verify the 
exception message or type. Consider adding assertions to verify that the 
correct exception is thrown with an appropriate error message about the 
timeout, to ensure the error handling path works as expected.



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1874,42 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  @Timeout(15)
+  void testGetFileSystemTimeoutThrowsException() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    try (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 -> {
+                // Block 100s, however, the timeout is set to 6s by default in
+                // FilesetCatalogOperations, so it's expected to be over 
within 10s
+                Awaitility.await().forever().until(() -> false);

Review Comment:
   The test uses `Awaitility.await().forever().until(() -> false)` to simulate 
a blocking call. However, this creates a busy-wait loop that consumes CPU 
unnecessarily. Consider using `Thread.sleep(Long.MAX_VALUE)` or 
`CountDownLatch.await()` instead, which would be more efficient and clearer in 
intent.
   ```suggestion
                   Thread.sleep(Long.MAX_VALUE);
   ```



##########
bundles/gcp/src/main/java/org/apache/gravitino/gcs/fs/GCSFileSystemProvider.java:
##########
@@ -71,4 +77,30 @@ public String scheme() {
   public String name() {
     return "gcs";
   }
+
+  /**
+   * Add additional GCS specific configuration to tune the performance.
+   *
+   * @param configs original configuration
+   * @return the configuration with additional GCS tuning parameters
+   */
+  private Map<String, String> additionalGCSConfig(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 
GoogleHadoopFileSystemBase.GCS_HTTP_CONNECT_TIMEOUT_KEY to avoid
+    // dependency on a specific Hadoop version
+    if (!configs.containsKey(GCS_GCS_HTTP_CONNECT_TIMEOUT_KEY)) {
+      //

Review Comment:
   The comment on line 94 is incomplete - it starts with "//" but has no 
content. This should either be removed or completed with meaningful 
documentation.
   ```suggestion
   
   ```



##########
catalogs/catalog-fileset/src/test/java/org/apache/gravitino/catalog/fileset/TestFilesetCatalogOperations.java:
##########
@@ -1868,6 +1874,42 @@ public void testGetTargetLocation() throws IOException {
     }
   }
 
+  @Test
+  @Timeout(15)
+  void testGetFileSystemTimeoutThrowsException() throws Exception {
+    FieldUtils.writeField(
+        GravitinoEnv.getInstance(), "entityStore", new 
RelationalEntityStore(), true);
+
+    try (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 -> {
+                // Block 100s, however, the timeout is set to 6s by default in
+                // FilesetCatalogOperations, so it's expected to be over 
within 10s
+                Awaitility.await().forever().until(() -> false);
+                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) {
+        long timeTake = System.currentTimeMillis() - now;
+        Assertions.assertTrue(timeTake <= 10000);
+      }

Review Comment:
   The test doesn't verify that the exception is actually thrown - it silently 
catches IOException and only checks the timing. If no exception is thrown, the 
test will pass incorrectly. Consider using `Assertions.assertThrows()` to 
ensure an IOException is thrown, then verify the timing within that context.
   ```suggestion
         // Test the following method should finish with 10s and throw 
IOException
         Assertions.assertThrows(
             IOException.class,
             () -> {
               long now = System.currentTimeMillis();
               try {
                 filesetCatalogOperations.getFileSystem(new 
Path("file:///tmp"), ImmutableMap.of());
               } finally {
                 long timeTake = System.currentTimeMillis() - now;
                 Assertions.assertTrue(timeTake <= 10000, "Timeout should occur 
within 10 seconds");
               }
             });
   ```



-- 
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