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); } /**