Closed chaohengstudent closed 1 year ago
這是在 local fs 才會遇到的問題嗎
這是在 local fs 才會遇到的問題嗎
是的,其他檔案系統的連線數只會跟隨 maxTasks
的數量增加,也會在 connector 關閉時結束連線,只有 local
就算只有一個 task
也會耗盡所有連線數
或許我們要考慮將 list
相關操作改成回傳Stream
,避免真的一次開啟大量的檔案/目錄
你覺得呢?
有道理,那我再發 Pr 調整
避免真的一次開啟大量的檔案/目錄
在做一些修改後,我覺得錯誤應該不是因為一次開啟大量檔案造成的,
每次的listFiles()
或 listFolder()
都只會開啟當下的目錄並且應該要在回傳子目錄的字串的 List 後就直接關閉,
主要是因為在使用到 Files.list()
後 "在回傳子目錄的字串後就直接關閉"
這段沒有被執行,導致 task 在多次 poll 後累積了大量開啟的目錄從未關閉。
我的想法是需要透過 try-with-resource 讓這個目錄回傳字串的 List
後在流結束時關閉。
private synchronized List<String> listFolders(String path, boolean requireFile) {
var folder = resolvePath(path);
if (!Files.isDirectory(folder)) throw new IllegalArgumentException(path + " is not a folder");
// 確保資源在流完成時關閉
try (var paths = Utils.packException(() -> Files.list(folder))) {
return paths
.filter(f -> requireFile ? Files.isRegularFile(f) : Files.isDirectory(f))
.map(Path::toAbsolutePath)
.map(
p ->
Path.of("/")
.resolve(
root.map(r -> p.subpath(Path.of(r).getNameCount(), p.getNameCount()))
.orElse(p))
.toString())
.collect(Collectors.toList());
}
}
若是直接回傳 Stream
會讓這些資源需要在外部額外各自去關閉,所以仍然使用 List
不知道是否有其他能修改的方向。
我的想法是需要透過 try-with-resource 讓這個目錄回傳字串的 List 後在流結束時關閉。
這個方法可以試試看
當
Importer
在使用local
的 file system 時會因為Files.list()
產生Too many open files
錯誤根據 doc
因此我的想法是將這段程式碼包裝在 try-with-resources,想請教是否合理 https://github.com/skiptests/astraea/blob/69c29a37021bd27ddb1fdcaf1d5c1a113d2aacea/fs/src/main/java/org/astraea/fs/local/LocalFileSystem.java#L76-L86