From cd6bcf5f9ab0ebfd1788514816901e6acfb97230 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Sun, 12 Apr 2026 03:41:40 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=20Bolt:=20Use=20sliding=20window=20fo?= =?UTF-8?q?r=20TaskGroup=20concurrency=20in=20ProcessMemoryScanner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: acebytes <2820910+acebytes@users.noreply.github.com> --- .jules/bolt.md | 3 ++ .../Memory/ProcessMemoryScanner.swift | 40 +++++++++++-------- 2 files changed, 27 insertions(+), 16 deletions(-) create mode 100644 .jules/bolt.md diff --git a/.jules/bolt.md b/.jules/bolt.md new file mode 100644 index 0000000..d44fbbd --- /dev/null +++ b/.jules/bolt.md @@ -0,0 +1,3 @@ +## 2025-04-12 - TaskGroup Sliding Window Concurrency Optimization +**Learning:** When using Swift's `withTaskGroup` for high-volume concurrent processing (e.g., scanning hundreds of PIDs), grouping tasks into static chunks and waiting for the chunk to finish causes tail latency. The entire chunk waits for the slowest task to complete, temporarily dropping concurrency to 1. +**Action:** Always use a sliding window approach with an iterator (e.g., `makeIterator()`). Seed the group up to the `maxConcurrency` limit, and within the `for await result in group` loop, immediately add a new task using `iterator.next()`. This ensures the worker pool stays consistently saturated at max concurrency. \ No newline at end of file diff --git a/Sources/Cacheout/Memory/ProcessMemoryScanner.swift b/Sources/Cacheout/Memory/ProcessMemoryScanner.swift index 3f8e728..0732586 100644 --- a/Sources/Cacheout/Memory/ProcessMemoryScanner.swift +++ b/Sources/Cacheout/Memory/ProcessMemoryScanner.swift @@ -97,29 +97,37 @@ actor ProcessMemoryScanner { /// /// Returns the collected entries and the count of EPERM failures. private func scanPIDs(_ pids: [pid_t]) async -> (entries: [ProcessEntryDTO], epermCount: Int) { - // Chunk PIDs to cap concurrency at maxConcurrency. - let chunks = stride(from: 0, to: pids.count, by: maxConcurrency).map { - Array(pids[$0..