Skip to content

Commit 705bacc

Browse files
refactor: consolidate duplicate bounded-concurrency helpers onto mapWithConcurrency (#6602)
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
1 parent 3f6591d commit 705bacc

2 files changed

Lines changed: 9 additions & 23 deletions

File tree

src/queue/patchless-secret-scan.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { FileFetcher } from "../review/review-grounding";
2+
import { mapWithConcurrency } from "./map-with-concurrency";
23
import type { AdvisoryFinding, PullRequestFileRecord } from "../types";
34

45
/** Per-file cap when synthesizing a patch for GitHub's patch-less (binary/large) PR files. */
@@ -154,22 +155,14 @@ export function incompletePatchLessSecretScanFinding(
154155
};
155156
}
156157

158+
// Bounded-concurrency fan-out over the patch-less files. Delegates to the canonical `mapWithConcurrency`
159+
// (#6602) — the worker-pool loop lives in exactly one place under src/queue and src/signals.
157160
async function mapPatchLessSecretScanFilesWithConcurrency<T, R>(
158161
items: T[],
159162
limit: number,
160163
mapper: (item: T) => Promise<R>,
161164
): Promise<R[]> {
162-
const results: R[] = new Array(items.length);
163-
let nextIndex = 0;
164-
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
165-
while (nextIndex < items.length) {
166-
const index = nextIndex;
167-
nextIndex += 1;
168-
results[index] = await mapper(items[index]!);
169-
}
170-
});
171-
await Promise.all(workers);
172-
return results;
165+
return mapWithConcurrency(items, limit, mapper);
173166
}
174167

175168
/** When GitHub omits inline `patch` (binary/large files), fetch post-change content and synthesize `+` lines so

src/signals/focus-manifest-loader.ts

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { listSignalSnapshots, persistSignalSnapshot } from "../db/repositories";
2+
import { mapWithConcurrency } from "../queue/map-with-concurrency";
23
import type { JsonValue } from "../types";
34
import { nowIso } from "../utils/json";
45
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<string | nul
235236
}
236237
}
237238

238-
/** Bounded-concurrency fan-out: runs `mapper` over `items` with at most `limit` in flight at once (#3899). */
239+
/** Bounded-concurrency fan-out: runs `mapper` over `items` with at most `limit` in flight at once (#3899).
240+
* Delegates to the canonical `mapWithConcurrency` (#6602) so the worker-pool loop lives in exactly one place;
241+
* the name and `(items, limit, mapper)` signature are preserved for existing callers. */
239242
export async function mapWithConcurrencyLimit<T, U>(items: T[], limit: number, mapper: (item: T) => Promise<U>): Promise<U[]> {
240-
const results: U[] = new Array(items.length);
241-
let nextIndex = 0;
242-
const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
243-
while (nextIndex < items.length) {
244-
const index = nextIndex;
245-
nextIndex += 1;
246-
results[index] = await mapper(items[index]!);
247-
}
248-
});
249-
await Promise.all(workers);
250-
return results;
243+
return mapWithConcurrency(items, limit, mapper);
251244
}
252245

253246
/**

0 commit comments

Comments
 (0)