From a7d0671e773478082f3abaaab6898fc8b11d5c4f Mon Sep 17 00:00:00 2001 From: Albert Puig Date: Tue, 16 Dec 2025 18:03:34 +0100 Subject: [PATCH] Limit FileEventStream.read() to 1000 files per iteration Replace listFiles() with File.walk().take(1000) to prevent scanning excessive files in directories with tens of thousands of event files. Improves performance and reduces resource usage during flush cycles. --- .../kotlin/core/utilities/EventStream.kt | 7 +++- .../kotlin/core/utilities/EventStreamTest.kt | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventStream.kt b/core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventStream.kt index 5ee3ed00..de672e46 100644 --- a/core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventStream.kt +++ b/core/src/main/java/com/segment/analytics/kotlin/core/utilities/EventStream.kt @@ -203,7 +203,12 @@ open class FileEventStream( } } - override fun read(): List = (directory.listFiles() ?: emptyArray()).map { it.absolutePath } + override fun read(): List = directory.walk() + .maxDepth(1) + .filter { it.isFile } + .take(1000) + .map { it.absolutePath } + .toList() /** * Remove the given file from disk diff --git a/core/src/test/kotlin/com/segment/analytics/kotlin/core/utilities/EventStreamTest.kt b/core/src/test/kotlin/com/segment/analytics/kotlin/core/utilities/EventStreamTest.kt index 5339e9e8..453cb3b2 100644 --- a/core/src/test/kotlin/com/segment/analytics/kotlin/core/utilities/EventStreamTest.kt +++ b/core/src/test/kotlin/com/segment/analytics/kotlin/core/utilities/EventStreamTest.kt @@ -266,5 +266,43 @@ class EventStreamTest { assertEquals("test", files[0]) assertFalse(eventStream.isOpened) } + + @Test + fun readLimitsTo1000FilesTest() { + // Create 1250 files in the directory + for (i in 1..1250) { + File(dir, "test$i.tmp").createNewFile() + } + + val files = eventStream.read() + + // Verify that read() returns at most 1000 files + assertTrue(files.size <= 1000, "Expected at most 1000 files, but got ${files.size}") + + // Verify all returned paths are valid files + files.forEach { path -> + assertTrue(File(path).exists(), "File $path should exist") + assertTrue(File(path).isFile, "Path $path should be a file") + } + } + + @Test + fun readReturnsAllFilesWhenUnder1000Test() { + // Create 50 files in the directory + for (i in 1..50) { + File(dir, "test$i.tmp").createNewFile() + } + + val files = eventStream.read() + + // Verify that all 50 files are returned when count is under 1000 + assertEquals(50, files.size, "Expected 50 files, but got ${files.size}") + + // Verify all returned paths are valid files + files.forEach { path -> + assertTrue(File(path).exists(), "File $path should exist") + assertTrue(File(path).isFile, "Path $path should be a file") + } + } } } \ No newline at end of file