From 2df8967ae27851e79d7c665483456825a21a6e6d Mon Sep 17 00:00:00 2001 From: Sergei Zharinov <zharinov@users.noreply.github.com> Date: Tue, 6 Sep 2022 13:36:51 +0300 Subject: [PATCH] refactor: Create promises utilities (#17651) --- .../datasource/galaxy-collection/index.ts | 7 +++-- lib/modules/datasource/go/releases-goproxy.ts | 4 +-- lib/modules/datasource/maven/index.ts | 4 +-- lib/modules/datasource/nuget/v3.ts | 6 ++--- lib/modules/datasource/packagist/index.ts | 4 +-- .../datasource/terraform-provider/index.ts | 4 +-- lib/modules/manager/hermit/artifacts.ts | 17 +++++------- .../manager/terraform/lockfile/hash.ts | 10 +++---- .../manager/terraform/lockfile/index.ts | 6 ++--- lib/modules/platform/gitlab/index.ts | 7 ++--- lib/util/http/github.ts | 4 +-- lib/util/promises.ts | 27 +++++++++++++++++++ lib/workers/repository/changelog/index.ts | 4 +-- lib/workers/repository/process/fetch.ts | 6 ++--- .../repository/process/vulnerabilities.ts | 8 +++--- 15 files changed, 66 insertions(+), 52 deletions(-) create mode 100644 lib/util/promises.ts diff --git a/lib/modules/datasource/galaxy-collection/index.ts b/lib/modules/datasource/galaxy-collection/index.ts index 1839445f1e..0d89d1b1c0 100644 --- a/lib/modules/datasource/galaxy-collection/index.ts +++ b/lib/modules/datasource/galaxy-collection/index.ts @@ -1,8 +1,8 @@ import is from '@sindresorhus/is'; -import pMap from 'p-map'; import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; import type { HttpResponse } from '../../../util/http/types'; +import * as p from '../../../util/promises'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; import type { @@ -76,7 +76,7 @@ export class GalaxyCollectionDatasource extends Datasource { let newestVersionDetails: VersionsDetailResult | undefined; // asynchronously get release details - const enrichedReleases: (Release | null)[] = await pMap( + const enrichedReleases: (Release | null)[] = await p.map( releases, (basicRelease) => this.http @@ -108,8 +108,7 @@ export class GalaxyCollectionDatasource extends Datasource { ); return null; } - }), - { concurrency: 5 } // allow 5 requests at maximum in parallel + }) ); // filter failed versions const filteredReleases = enrichedReleases.filter(is.truthy); diff --git a/lib/modules/datasource/go/releases-goproxy.ts b/lib/modules/datasource/go/releases-goproxy.ts index 0f98bbfbf9..89bcbe95d0 100644 --- a/lib/modules/datasource/go/releases-goproxy.ts +++ b/lib/modules/datasource/go/releases-goproxy.ts @@ -1,8 +1,8 @@ import is from '@sindresorhus/is'; import moo from 'moo'; -import pAll from 'p-all'; import { logger } from '../../../logger'; import { cache } from '../../../util/cache/package/decorator'; +import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; import { Datasource } from '../datasource'; import type { GetReleasesConfig, Release, ReleaseResult } from '../types'; @@ -60,7 +60,7 @@ export class GoProxyDatasource extends Datasource { return { version }; } }); - const releases = await pAll(queue, { concurrency: 5 }); + const releases = await p.all(queue); if (releases.length) { const datasource = await BaseGoDatasource.getDatasource(packageName); const sourceUrl = getSourceUrl(datasource); diff --git a/lib/modules/datasource/maven/index.ts b/lib/modules/datasource/maven/index.ts index aa95a813cb..19e327ec7d 100644 --- a/lib/modules/datasource/maven/index.ts +++ b/lib/modules/datasource/maven/index.ts @@ -1,9 +1,9 @@ import is from '@sindresorhus/is'; import { DateTime } from 'luxon'; -import pAll from 'p-all'; import type { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import * as packageCache from '../../../util/cache/package'; +import * as p from '../../../util/promises'; import { newlineRegex, regEx } from '../../../util/regex'; import { ensureTrailingSlash } from '../../../util/url'; import mavenVersion from '../../versioning/maven'; @@ -268,7 +268,7 @@ export class MavenDatasource extends Datasource { res !== 'not-found' && res !== 'error' ? release : null; }); - await pAll(queue, { concurrency: 5 }); + await p.all(queue); if (!isCacheValid) { // Store new TTL flag for 24 hours if the previous one is invalidated diff --git a/lib/modules/datasource/nuget/v3.ts b/lib/modules/datasource/nuget/v3.ts index d389392391..42b4b8e170 100644 --- a/lib/modules/datasource/nuget/v3.ts +++ b/lib/modules/datasource/nuget/v3.ts @@ -1,11 +1,11 @@ import is from '@sindresorhus/is'; -import pAll from 'p-all'; import semver from 'semver'; import { XmlDocument } from 'xmldoc'; import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import * as packageCache from '../../../util/cache/package'; import { Http, HttpError } from '../../../util/http'; +import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; import { ensureTrailingSlash } from '../../../util/url'; import type { Release, ReleaseResult } from '../types'; @@ -121,9 +121,7 @@ export async function getReleases( const catalogPagesQueue = catalogPages.map( (page) => (): Promise<CatalogEntry[]> => getCatalogEntry(http, page) ); - const catalogEntries = ( - await pAll(catalogPagesQueue, { concurrency: 5 }) - ).flat(); + const catalogEntries = (await p.all(catalogPagesQueue)).flat(); let homepage: string | null = null; let latestStable: string | null = null; diff --git a/lib/modules/datasource/packagist/index.ts b/lib/modules/datasource/packagist/index.ts index 48a947215b..4bf0110466 100644 --- a/lib/modules/datasource/packagist/index.ts +++ b/lib/modules/datasource/packagist/index.ts @@ -1,11 +1,11 @@ import URL from 'url'; -import pAll from 'p-all'; import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import * as packageCache from '../../../util/cache/package'; import { cache } from '../../../util/cache/package/decorator'; import * as hostRules from '../../../util/host-rules'; import type { HttpOptions } from '../../../util/http/types'; +import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; import { ensureTrailingSlash, joinUrlParts } from '../../../util/url'; import * as composerVersioning from '../../versioning/composer'; @@ -182,7 +182,7 @@ export class PackagistDatasource extends Datasource { (file) => (): Promise<PackagistFile> => this.getPackagistFile(regUrl, file) ); - const resolvedFiles = await pAll(queue, { concurrency: 5 }); + const resolvedFiles = await p.all(queue); for (const res of resolvedFiles) { for (const [name, val] of Object.entries(res.providers)) { providerPackages[name] = val.sha256; diff --git a/lib/modules/datasource/terraform-provider/index.ts b/lib/modules/datasource/terraform-provider/index.ts index c2f1882dd7..c968a5eecf 100644 --- a/lib/modules/datasource/terraform-provider/index.ts +++ b/lib/modules/datasource/terraform-provider/index.ts @@ -1,10 +1,10 @@ // TODO: types (#7154) /* eslint-disable @typescript-eslint/restrict-template-expressions */ import is from '@sindresorhus/is'; -import pMap from 'p-map'; import { logger } from '../../../logger'; import { ExternalHostError } from '../../../types/errors/external-host-error'; import { cache } from '../../../util/cache/package/decorator'; +import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; import * as hashicorpVersioning from '../../versioning/hashicorp'; import { TerraformDatasource } from '../terraform-module/base'; @@ -230,7 +230,7 @@ export class TerraformProviderDatasource extends TerraformDatasource { ); return null; } - const result = await pMap( + const result = await p.map( builds.platforms, async (platform) => { const buildURL = `${backendURL}/${version}/download/${platform.os}/${platform.arch}`; diff --git a/lib/modules/manager/hermit/artifacts.ts b/lib/modules/manager/hermit/artifacts.ts index 40a337a937..d6e1adbc5f 100644 --- a/lib/modules/manager/hermit/artifacts.ts +++ b/lib/modules/manager/hermit/artifacts.ts @@ -1,10 +1,10 @@ -import pMap from 'p-map'; import upath from 'upath'; import { logger } from '../../../logger'; import { exec } from '../../../util/exec'; import type { ExecOptions } from '../../../util/exec/types'; import { localPathIsSymbolicLink, readLocalSymlink } from '../../../util/fs'; import { getRepoStatus } from '../../../util/git'; +import * as p from '../../../util/promises'; import type { UpdateArtifact, UpdateArtifactsResult } from '../types'; import type { ReadContentResult } from './types'; @@ -119,19 +119,18 @@ async function getUpdateResult( ); // handle added files - const added = await pMap( + const added = await p.map( [...hermitChanges.created, ...hermitChanges.not_added], async (path: string): Promise<UpdateArtifactsResult> => { const contents = await getContent(path); return getAddResult(path, contents); - }, - { concurrency: 5 } + } ); const deleted = hermitChanges.deleted.map(getDeleteResult); - const modified = await pMap( + const modified = await p.map( hermitChanges.modified, async (path: string): Promise<UpdateArtifactsResult[]> => { const contents = await getContent(path); @@ -139,11 +138,10 @@ async function getUpdateResult( getDeleteResult(path), // delete existing link getAddResult(path, contents), // add a new link ]; - }, - { concurrency: 5 } + } ); - const renamed = await pMap( + const renamed = await p.map( hermitChanges.renamed, async (renamed): Promise<UpdateArtifactsResult[]> => { const from = renamed.from; @@ -151,8 +149,7 @@ async function getUpdateResult( const toContents = await getContent(to); return [getDeleteResult(from), getAddResult(to, toContents)]; - }, - { concurrency: 5 } + } ); return [ diff --git a/lib/modules/manager/terraform/lockfile/hash.ts b/lib/modules/manager/terraform/lockfile/hash.ts index 47556aee44..d3b3757163 100644 --- a/lib/modules/manager/terraform/lockfile/hash.ts +++ b/lib/modules/manager/terraform/lockfile/hash.ts @@ -1,12 +1,12 @@ import crypto from 'crypto'; import extract from 'extract-zip'; -import pMap from 'p-map'; import upath from 'upath'; import { logger } from '../../../../logger'; import { cache } from '../../../../util/cache/package/decorator'; import * as fs from '../../../../util/fs'; import { ensureCacheDir } from '../../../../util/fs'; import { Http } from '../../../../util/http'; +import * as p from '../../../../util/promises'; import { regEx } from '../../../../util/regex'; import { TerraformProviderDatasource } from '../../../datasource/terraform-provider'; import type { TerraformBuild } from '../../../datasource/terraform-provider/types'; @@ -94,11 +94,9 @@ export class TerraformProviderHash { const cacheDir = await ensureCacheDir('./others/terraform'); // for each build download ZIP, extract content and generate hash for all containing files - return pMap( - builds, - (build) => this.calculateSingleHash(build, cacheDir), - { concurrency: 4 } // allow to look up 4 builds for this version in parallel - ); + return p.map(builds, (build) => this.calculateSingleHash(build, cacheDir), { + concurrency: 4, + }); } static async createHashes( diff --git a/lib/modules/manager/terraform/lockfile/index.ts b/lib/modules/manager/terraform/lockfile/index.ts index f2aee3eab9..69d7968d1a 100644 --- a/lib/modules/manager/terraform/lockfile/index.ts +++ b/lib/modules/manager/terraform/lockfile/index.ts @@ -1,6 +1,6 @@ import is from '@sindresorhus/is'; -import pMap from 'p-map'; import { logger } from '../../../../logger'; +import * as p from '../../../../util/promises'; import { GetPkgReleasesConfig, getPkgReleases } from '../../../datasource'; import { TerraformProviderDatasource } from '../../../datasource/terraform-provider'; import { get as getVersioning } from '../../../versioning'; @@ -19,7 +19,7 @@ import { async function updateAllLocks( locks: ProviderLock[] ): Promise<ProviderLockUpdate[]> { - const updates = await pMap( + const updates = await p.map( locks, async (lock) => { const updateConfig: GetPkgReleasesConfig = { @@ -56,7 +56,7 @@ async function updateAllLocks( }; return update; }, - { concurrency: 4 } // allow to look up 4 lock in parallel + { concurrency: 4 } ); return updates.filter(is.truthy); diff --git a/lib/modules/platform/gitlab/index.ts b/lib/modules/platform/gitlab/index.ts index 2069b99948..805b32f555 100644 --- a/lib/modules/platform/gitlab/index.ts +++ b/lib/modules/platform/gitlab/index.ts @@ -2,7 +2,6 @@ import URL from 'url'; import is from '@sindresorhus/is'; import delay from 'delay'; import JSON5 from 'json5'; -import pAll from 'p-all'; import semver from 'semver'; import { PlatformId } from '../../../constants'; import { @@ -23,6 +22,7 @@ import * as git from '../../../util/git'; import * as hostRules from '../../../util/host-rules'; import { setBaseUrl } from '../../../util/http/gitlab'; import type { HttpResponse } from '../../../util/http/types'; +import * as p from '../../../util/promises'; import { regEx } from '../../../util/regex'; import { sanitize } from '../../../util/sanitize'; import { @@ -1014,10 +1014,7 @@ export async function addReviewers( // Gather the IDs for all the reviewers we want to add let newReviewerIDs: number[]; try { - newReviewerIDs = await pAll( - newReviewers.map((r) => () => getUserID(r)), - { concurrency: 5 } - ); + newReviewerIDs = await p.all(newReviewers.map((r) => () => getUserID(r))); } catch (err) { logger.warn({ err }, 'Failed to get IDs of the new reviewers'); return; diff --git a/lib/util/http/github.ts b/lib/util/http/github.ts index 1350088968..2f5eca7ebe 100644 --- a/lib/util/http/github.ts +++ b/lib/util/http/github.ts @@ -1,6 +1,5 @@ import is from '@sindresorhus/is'; import { DateTime } from 'luxon'; -import pAll from 'p-all'; import { PlatformId } from '../../constants'; import { PLATFORM_BAD_CREDENTIALS, @@ -12,6 +11,7 @@ import { logger } from '../../logger'; import { ExternalHostError } from '../../types/errors/external-host-error'; import { getCache } from '../cache/repository'; import { maskToken } from '../mask'; +import * as p from '../promises'; import { range } from '../range'; import { regEx } from '../regex'; import { joinUrlParts, parseLinkHeader, resolveBaseUrl } from '../url'; @@ -335,7 +335,7 @@ export class GithubHttp extends Http<GithubHttpOptions, GithubHttpOptions> { ); } ); - const pages = await pAll(queue, { concurrency: 5 }); + const pages = await p.all(queue); if (opts.paginationField && is.plainObject(result.body)) { const paginatedResult = result.body[opts.paginationField]; if (is.array<T>(paginatedResult)) { diff --git a/lib/util/promises.ts b/lib/util/promises.ts new file mode 100644 index 0000000000..a0145ced65 --- /dev/null +++ b/lib/util/promises.ts @@ -0,0 +1,27 @@ +import pAll from 'p-all'; +import pMap from 'p-map'; + +type PromiseFactory<T> = () => Promise<T>; + +export function all<T>( + tasks: PromiseFactory<T>[], + options?: pAll.Options +): Promise<T[]> { + return pAll(tasks, { + concurrency: 5, + ...options, + stopOnError: true, + }); +} + +export function map<Element, NewElement>( + input: Iterable<Element>, + mapper: pMap.Mapper<Element, NewElement>, + options?: pMap.Options +): Promise<NewElement[]> { + return pMap(input, mapper, { + concurrency: 5, + ...options, + stopOnError: true, + }); +} diff --git a/lib/workers/repository/changelog/index.ts b/lib/workers/repository/changelog/index.ts index 9a141dc048..8bc6c45559 100644 --- a/lib/workers/repository/changelog/index.ts +++ b/lib/workers/repository/changelog/index.ts @@ -1,4 +1,4 @@ -import pMap from 'p-map'; +import * as p from '../../../util/promises'; import { containsTemplates, exposedConfigOptions, @@ -19,7 +19,7 @@ export async function embedChangelog( export async function embedChangelogs( branches: BranchUpgradeConfig[] ): Promise<void> { - await pMap(branches, embedChangelog, { concurrency: 10 }); + await p.map(branches, embedChangelog, { concurrency: 10 }); } export function needsChangelogs( diff --git a/lib/workers/repository/process/fetch.ts b/lib/workers/repository/process/fetch.ts index f6b5deea3e..aed4095355 100644 --- a/lib/workers/repository/process/fetch.ts +++ b/lib/workers/repository/process/fetch.ts @@ -1,6 +1,5 @@ // TODO #7154 import is from '@sindresorhus/is'; -import pAll from 'p-all'; import { getManagerConfig, mergeChildConfig } from '../../../config'; import type { RenovateConfig } from '../../../config/types'; import { logger } from '../../../logger'; @@ -15,6 +14,7 @@ import type { import { ExternalHostError } from '../../../types/errors/external-host-error'; import { clone } from '../../../util/clone'; import { applyPackageRules } from '../../../util/package-rules'; +import * as p from '../../../util/promises'; import { PackageFiles } from '../package-files'; import { lookupUpdates } from './lookup'; import type { LookupUpdateConfig } from './lookup/types'; @@ -96,7 +96,7 @@ async function fetchManagerPackagerFileUpdates( 'fetchManagerPackagerFileUpdates starting with concurrency' ); - pFile.deps = await pAll(queue, { concurrency: 5 }); + pFile.deps = await p.all(queue); logger.trace({ packageFile }, 'fetchManagerPackagerFileUpdates finished'); } @@ -114,7 +114,7 @@ async function fetchManagerUpdates( { manager, queueLength: queue.length }, 'fetchManagerUpdates starting' ); - await pAll(queue, { concurrency: 5 }); + await p.all(queue); logger.trace({ manager }, 'fetchManagerUpdates finished'); } diff --git a/lib/workers/repository/process/vulnerabilities.ts b/lib/workers/repository/process/vulnerabilities.ts index 9cbe6c9da7..0171dee232 100644 --- a/lib/workers/repository/process/vulnerabilities.ts +++ b/lib/workers/repository/process/vulnerabilities.ts @@ -1,6 +1,5 @@ // TODO #7154 import { Ecosystem, Osv, OsvOffline } from '@jamiemagee/osv-offline'; -import pAll from 'p-all'; import { getManagerConfig, mergeChildConfig } from '../../../config'; import type { PackageRule, RenovateConfig } from '../../../config/types'; import { logger } from '../../../logger'; @@ -8,6 +7,7 @@ import type { PackageDependency, PackageFile, } from '../../../modules/manager/types'; +import * as p from '../../../util/promises'; export class Vulnerabilities { private osvOffline: OsvOffline | undefined; @@ -73,7 +73,7 @@ export class Vulnerabilities { { manager, queueLength: queue.length }, 'fetchManagerUpdates starting' ); - await pAll(queue, { concurrency: 5 }); + await p.all(queue); logger.trace({ manager }, 'fetchManagerUpdates finished'); } @@ -94,9 +94,7 @@ export class Vulnerabilities { 'fetchManagerPackagerFileUpdates starting with concurrency' ); - config.packageRules?.push( - ...(await pAll(queue, { concurrency: 5 })).flat() - ); + config.packageRules?.push(...(await p.all(queue)).flat()); logger.trace({ packageFile }, 'fetchManagerPackagerFileUpdates finished'); } -- GitLab