Skip to content

Commit eb37958

Browse files
authored
refactor: Flatten package lookup queue (#32930)
1 parent 735ea20 commit eb37958

File tree

3 files changed

+82
-51
lines changed

3 files changed

+82
-51
lines changed

lib/util/promises.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function isExternalHostError(err: any): err is ExternalHostError {
1010
return err instanceof ExternalHostError;
1111
}
1212

13-
function handleMultipleErrors(errors: Error[]): never {
13+
export function handleMultipleErrors(errors: Error[]): never {
1414
const hostError = errors.find(isExternalHostError);
1515
if (hostError) {
1616
throw hostError;

lib/workers/repository/process/fetch.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { getConfig } from '../../../config/defaults';
44
import { MavenDatasource } from '../../../modules/datasource/maven';
55
import type { PackageFile } from '../../../modules/manager/types';
66
import { ExternalHostError } from '../../../types/errors/external-host-error';
7+
import { Result } from '../../../util/result';
78
import { fetchUpdates } from './fetch';
89
import * as lookup from './lookup';
910

@@ -197,7 +198,7 @@ describe('workers/repository/process/fetch', () => {
197198
},
198199
],
199200
};
200-
lookupUpdates.mockRejectedValueOnce(new Error('some error'));
201+
lookupUpdates.mockResolvedValueOnce(Result.err(new Error('some error')));
201202

202203
await expect(
203204
fetchUpdates({ ...config, repoIsOnboarded: true }, packageFiles),
@@ -214,7 +215,7 @@ describe('workers/repository/process/fetch', () => {
214215
},
215216
],
216217
};
217-
lookupUpdates.mockRejectedValueOnce(new Error('some error'));
218+
lookupUpdates.mockResolvedValueOnce(Result.err(new Error('some error')));
218219

219220
await expect(
220221
fetchUpdates({ ...config, repoIsOnboarded: true }, packageFiles),

lib/workers/repository/process/fetch.ts

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ import type { LookupUpdateConfig, UpdateResult } from './lookup/types';
2121

2222
type LookupResult = Result<PackageDependency, Error>;
2323

24+
interface LookupTaskResult {
25+
packageFile: PackageFile;
26+
result: LookupResult;
27+
}
28+
29+
type LookupTask = Promise<LookupTaskResult>;
30+
2431
async function lookup(
2532
packageFileConfig: RenovateConfig & PackageFile,
2633
indep: PackageDependency,
@@ -106,63 +113,86 @@ async function lookup(
106113
});
107114
}
108115

109-
async function fetchManagerPackagerFileUpdates(
116+
function createLookupTasks(
110117
config: RenovateConfig,
111-
managerConfig: RenovateConfig,
112-
pFile: PackageFile,
113-
): Promise<void> {
114-
const { packageFile } = pFile;
115-
const packageFileConfig = mergeChildConfig(managerConfig, pFile);
116-
if (pFile.extractedConstraints) {
117-
packageFileConfig.constraints = {
118-
...pFile.extractedConstraints,
119-
...config.constraints,
120-
};
118+
managerPackageFiles: Record<string, PackageFile[]>,
119+
): LookupTask[] {
120+
const lookupTasks: LookupTask[] = [];
121+
122+
for (const [manager, packageFiles] of Object.entries(managerPackageFiles)) {
123+
const managerConfig = getManagerConfig(config, manager);
124+
125+
for (const packageFile of packageFiles) {
126+
const packageFileConfig = mergeChildConfig(managerConfig, packageFile);
127+
if (packageFile.extractedConstraints) {
128+
packageFileConfig.constraints = {
129+
...packageFile.extractedConstraints,
130+
...config.constraints,
131+
};
132+
}
133+
134+
for (const dep of packageFile.deps) {
135+
lookupTasks.push(
136+
lookup(packageFileConfig, dep).then((result) => ({
137+
packageFile,
138+
result,
139+
})),
140+
);
141+
}
142+
}
121143
}
122-
const { manager } = packageFileConfig;
123-
const queue = pFile.deps.map(
124-
(dep) => async (): Promise<PackageDependency> => {
125-
const updates = await lookup(packageFileConfig, dep);
126-
return updates.unwrapOrThrow();
127-
},
128-
);
129-
logger.trace(
130-
{ manager, packageFile, queueLength: queue.length },
131-
'fetchManagerPackagerFileUpdates starting with concurrency',
132-
);
133144

134-
pFile.deps = await p.all(queue);
135-
logger.trace({ packageFile }, 'fetchManagerPackagerFileUpdates finished');
136-
}
137-
138-
async function fetchManagerUpdates(
139-
config: RenovateConfig,
140-
packageFiles: Record<string, PackageFile[]>,
141-
manager: string,
142-
): Promise<void> {
143-
const managerConfig = getManagerConfig(config, manager);
144-
const queue = packageFiles[manager].map(
145-
(pFile) => (): Promise<void> =>
146-
fetchManagerPackagerFileUpdates(config, managerConfig, pFile),
147-
);
148-
logger.trace(
149-
{ manager, queueLength: queue.length },
150-
'fetchManagerUpdates starting',
151-
);
152-
await p.all(queue);
153-
logger.trace({ manager }, 'fetchManagerUpdates finished');
145+
return lookupTasks;
154146
}
155147

156148
export async function fetchUpdates(
157149
config: RenovateConfig,
158-
packageFiles: Record<string, PackageFile[]>,
150+
managerPackageFiles: Record<string, PackageFile[]>,
159151
): Promise<void> {
160-
const managers = Object.keys(packageFiles);
161-
const allManagerJobs = managers.map((manager) =>
162-
fetchManagerUpdates(config, packageFiles, manager),
152+
logger.debug(
153+
{ baseBranch: config.baseBranch },
154+
'Starting package releases lookups',
163155
);
164-
await Promise.all(allManagerJobs);
165-
PackageFiles.add(config.baseBranch!, { ...packageFiles });
156+
157+
const allTasks = createLookupTasks(config, managerPackageFiles);
158+
159+
const fetchResults = await Promise.all(allTasks);
160+
161+
const errors: Error[] = [];
162+
163+
type PackageDeps = WeakMap<PackageFile, PackageDependency[]>;
164+
const packageDeps: PackageDeps = new WeakMap();
165+
166+
// Separate good results from errors
167+
for (const { packageFile, result } of fetchResults) {
168+
const { val: dep, err } = result.unwrap();
169+
if (dep) {
170+
let deps = packageDeps.get(packageFile);
171+
if (!deps) {
172+
deps = [];
173+
packageDeps.set(packageFile, deps);
174+
}
175+
deps.push(dep);
176+
} else {
177+
errors.push(err);
178+
}
179+
}
180+
181+
if (errors.length) {
182+
p.handleMultipleErrors(errors);
183+
}
184+
185+
// Assign fetched deps back to packageFiles
186+
for (const packageFiles of Object.values(managerPackageFiles)) {
187+
for (const packageFile of packageFiles) {
188+
const packageFileDeps = packageDeps.get(packageFile);
189+
if (packageFileDeps) {
190+
packageFile.deps = packageFileDeps;
191+
}
192+
}
193+
}
194+
195+
PackageFiles.add(config.baseBranch!, { ...managerPackageFiles });
166196
logger.debug(
167197
{ baseBranch: config.baseBranch },
168198
'Package releases lookups complete',

0 commit comments

Comments
 (0)