diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..5ad3160 --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2024-05-04 - TaskGroup Serialization in Actors +**Learning:** In Swift Concurrency, when an actor creates a `TaskGroup` and its subtasks call an `isolated` method on the same actor, execution is serialized on the actor's executor, destroying parallelism. +**Action:** Mark computationally intensive or state-independent methods called from `TaskGroup` subtasks as `nonisolated` (like `NodeModulesScanner.findNodeModules`) so they run concurrently on the global pool. diff --git a/Sources/Cacheout/Scanner/NodeModulesScanner.swift b/Sources/Cacheout/Scanner/NodeModulesScanner.swift index 3ed4d8c..0306f0e 100644 --- a/Sources/Cacheout/Scanner/NodeModulesScanner.swift +++ b/Sources/Cacheout/Scanner/NodeModulesScanner.swift @@ -77,7 +77,8 @@ actor NodeModulesScanner { .sorted { $0.sizeBytes > $1.sizeBytes } } - private func findNodeModules(in directory: URL, maxDepth: Int, currentDepth: Int = 0) async -> [NodeModulesItem] { + nonisolated private func findNodeModules(in directory: URL, maxDepth: Int, currentDepth: Int = 0) async -> [NodeModulesItem] { + let fileManager = FileManager.default guard currentDepth < maxDepth else { return [] } var results: [NodeModulesItem] = [] @@ -120,7 +121,8 @@ actor NodeModulesScanner { return results } - private func directorySize(at url: URL) -> Int64 { + nonisolated private func directorySize(at url: URL) -> Int64 { + let fileManager = FileManager.default var total: Int64 = 0 guard let enumerator = fileManager.enumerator( at: url,