This is an automated email from the ASF dual-hosted git repository.

Jackie-Jiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new c27e3a77701 Close Files.walk stream in LocalLogFileServer to prevent 
file descriptor leak (#19242)
c27e3a77701 is described below

commit c27e3a777019b885e61ded96fc52d33c43574542
Author: Deepak kumar <[email protected]>
AuthorDate: Sat Aug 15 12:22:30 2026 -0700

    Close Files.walk stream in LocalLogFileServer to prevent file descriptor 
leak (#19242)
---
 .../pinot/common/utils/log/LocalLogFileServer.java |  9 ++++--
 .../common/utils/log/LocalLogFileServerTest.java   | 33 ++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/log/LocalLogFileServer.java
 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/log/LocalLogFileServer.java
index 5874ff6589c..701b67620b9 100644
--- 
a/pinot-common/src/main/java/org/apache/pinot/common/utils/log/LocalLogFileServer.java
+++ 
b/pinot-common/src/main/java/org/apache/pinot/common/utils/log/LocalLogFileServer.java
@@ -26,6 +26,7 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Set;
 import java.util.TreeSet;
+import java.util.stream.Stream;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
@@ -47,8 +48,12 @@ public class LocalLogFileServer implements LogFileServer {
   public Set<String> getAllLogFilePaths()
       throws IOException {
     Set<String> allFiles = new TreeSet<>();
-    Files.walk(_logRootDirPath).filter(Files::isRegularFile).forEach(
-        f -> 
allFiles.add(f.toAbsolutePath().toString().replace(_logRootDirPath.toAbsolutePath()
 + "/", "")));
+    // Files.walk holds one or more DirectoryStreams; close it eagerly so this 
method does not leak
+    // file descriptors when invoked repeatedly (e.g. once per downloadLogFile 
call).
+    try (Stream<Path> paths = Files.walk(_logRootDirPath)) {
+      paths.filter(Files::isRegularFile).forEach(
+          f -> 
allFiles.add(f.toAbsolutePath().toString().replace(_logRootDirPath.toAbsolutePath()
 + "/", "")));
+    }
     return allFiles;
   }
 
diff --git 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/log/LocalLogFileServerTest.java
 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/log/LocalLogFileServerTest.java
index 323379e57e3..19e9678509b 100644
--- 
a/pinot-common/src/test/java/org/apache/pinot/common/utils/log/LocalLogFileServerTest.java
+++ 
b/pinot-common/src/test/java/org/apache/pinot/common/utils/log/LocalLogFileServerTest.java
@@ -21,6 +21,7 @@ package org.apache.pinot.common.utils.log;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.util.Set;
 import javax.ws.rs.WebApplicationException;
 import javax.ws.rs.core.Response;
 import org.apache.commons.io.FileUtils;
@@ -29,6 +30,7 @@ import org.testng.annotations.Test;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
 
 public class LocalLogFileServerTest {
@@ -76,4 +78,35 @@ public class LocalLogFileServerTest {
       FileUtils.deleteQuietly(logRootDir);
     }
   }
+
+  /// Verifies that {@link LocalLogFileServer#getAllLogFilePaths()} enumerates 
files inside nested
+  /// subdirectories and returns paths that are relative to the log root. This 
is a regression test
+  /// for the {@code Files.walk} refactor that wraps the stream in a 
try-with-resources block; the
+  /// recursion behavior must be preserved so that downloads under nested 
directories continue to
+  /// work.
+  @Test
+  public void testGetAllLogFilePathsEnumeratesNestedDirectories()
+      throws IOException {
+    File logRootDir = new File(FileUtils.getTempDirectory(),
+        "testGetAllLogFilePathsEnumeratesNestedDirectories-" + 
System.currentTimeMillis());
+    try {
+      assertTrue(logRootDir.mkdirs());
+      File nested = new File(logRootDir, "sub/dir");
+      assertTrue(nested.mkdirs());
+      FileUtils.writeStringToFile(new File(logRootDir, "top.log"), "top", 
Charset.defaultCharset());
+      FileUtils.writeStringToFile(new File(nested, "nested.log"), "nested", 
Charset.defaultCharset());
+
+      LogFileServer logFileServer = new 
LocalLogFileServer(logRootDir.getAbsolutePath());
+      Set<String> paths = logFileServer.getAllLogFilePaths();
+
+      assertEquals(paths.size(), 2, "expected two enumerated files, got: " + 
paths);
+      assertTrue(paths.contains("top.log"), "missing top.log in " + paths);
+      assertTrue(paths.contains("sub/dir/nested.log"), "missing 
sub/dir/nested.log in " + paths);
+      // Both files must be downloadable via the relative paths returned above.
+      assertNotNull(logFileServer.downloadLogFile("top.log"));
+      assertNotNull(logFileServer.downloadLogFile("sub/dir/nested.log"));
+    } finally {
+      FileUtils.deleteQuietly(logRootDir);
+    }
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to