From 705baccd2f1ecee57c283feb2d1323f3d8262e7c Mon Sep 17 00:00:00 2001 From: jaytbarimbao-collab <300663773+jaytbarimbao-collab@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:54:20 -0400 Subject: [PATCH] refactor: consolidate duplicate bounded-concurrency helpers onto mapWithConcurrency (#6602) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit src/queue/map-with-concurrency.ts's mapWithConcurrency is the canonical bounded-concurrency worker-pool helper, but two hand-duplicated copies of the same loop had drifted in beside it: - src/signals/focus-manifest-loader.ts's exported mapWithConcurrencyLimit - src/queue/patchless-secret-scan.ts's private mapPatchLessSecretScanFilesWithConcurrency Both now delegate to mapWithConcurrency, keeping their existing names and (items, limit, mapper) signatures so every caller compiles and behaves unchanged (processors.ts uses both mapWithConcurrency and mapWithConcurrencyLimit side by side today). map-with-concurrency.ts is now the only file under src/queue or src/signals that implements the loop itself. Pure internal consolidation — no public behavior, signature, or export-name change. Covered by the existing caller suites (patchless-secret-scan, focus-manifest-loader/processors); no new test needed. Closes #6602 --- src/queue/patchless-secret-scan.ts | 15 ++++----------- src/signals/focus-manifest-loader.ts | 17 +++++------------ 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/src/queue/patchless-secret-scan.ts b/src/queue/patchless-secret-scan.ts index 0916c04dd8..e64dbb6495 100644 --- a/src/queue/patchless-secret-scan.ts +++ b/src/queue/patchless-secret-scan.ts @@ -1,4 +1,5 @@ import type { FileFetcher } from "../review/review-grounding"; +import { mapWithConcurrency } from "./map-with-concurrency"; import type { AdvisoryFinding, PullRequestFileRecord } from "../types"; /** Per-file cap when synthesizing a patch for GitHub's patch-less (binary/large) PR files. */ @@ -154,22 +155,14 @@ export function incompletePatchLessSecretScanFinding( }; } +// Bounded-concurrency fan-out over the patch-less files. Delegates to the canonical `mapWithConcurrency` +// (#6602) — the worker-pool loop lives in exactly one place under src/queue and src/signals. async function mapPatchLessSecretScanFilesWithConcurrency( items: T[], limit: number, mapper: (item: T) => Promise, ): Promise { - const results: R[] = new Array(items.length); - let nextIndex = 0; - const workers = Array.from({ length: Math.min(limit, items.length) }, async () => { - while (nextIndex < items.length) { - const index = nextIndex; - nextIndex += 1; - results[index] = await mapper(items[index]!); - } - }); - await Promise.all(workers); - return results; + return mapWithConcurrency(items, limit, mapper); } /** When GitHub omits inline `patch` (binary/large files), fetch post-change content and synthesize `+` lines so diff --git a/src/signals/focus-manifest-loader.ts b/src/signals/focus-manifest-loader.ts index 64f76e0a64..bb30d596ba 100644 --- a/src/signals/focus-manifest-loader.ts +++ b/src/signals/focus-manifest-loader.ts @@ -1,4 +1,5 @@ import { listSignalSnapshots, persistSignalSnapshot } from "../db/repositories"; +import { mapWithConcurrency } from "../queue/map-with-concurrency"; import type { JsonValue } from "../types"; import { nowIso } from "../utils/json"; import { contentLaneConfigToJson, experimentalConfigToJson, featuresConfigToJson, gateConfigToJson, MAX_FOCUS_MANIFEST_BYTES, parseFocusManifest, parseFocusManifestContent, repoDocGenerationConfigToJson, reviewConfigToJson, reviewRecapConfigToJson, maintainerRecapConfigToJson, opsConfigToJson, publicStatsConfigToJson, draftFlowConfigToJson, upstreamDriftIssuesConfigToJson, sweepWatchdogConfigToJson, prReconciliationConfigToJson, federatedIntelligenceConfigToJson, settingsOverrideToJson, type FocusManifest, type FocusManifestSource, type RepoReviewContext } from "./focus-manifest"; @@ -235,19 +236,11 @@ async function readBoundedResponseText(response: Response): Promise(items: T[], limit: number, mapper: (item: T) => Promise): Promise { - const results: U[] = new Array(items.length); - let nextIndex = 0; - const workers = Array.from({ length: Math.min(limit, items.length) }, async () => { - while (nextIndex < items.length) { - const index = nextIndex; - nextIndex += 1; - results[index] = await mapper(items[index]!); - } - }); - await Promise.all(workers); - return results; + return mapWithConcurrency(items, limit, mapper); } /**