mirror of https://github.com/nodejs/corepack.git
fix: streamline the cache exploration (#135)
If a large number of versions are cached on the host system, trying to read the whole cache at once can be quite memory intensive. Instead, we can use an iterative approach that doesn't hold the whole directory content in memory.
This commit is contained in:
parent
29da06c515
commit
185da44078
|
|
@ -1,4 +1,6 @@
|
|||
import {once} from 'events';
|
||||
import fs from 'fs';
|
||||
import type {Dir} from 'fs';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
|
||||
|
|
@ -45,30 +47,35 @@ export async function fetchAvailableVersions(spec: RegistrySpec): Promise<Array<
|
|||
export async function findInstalledVersion(installTarget: string, descriptor: Descriptor) {
|
||||
const installFolder = path.join(installTarget, descriptor.name);
|
||||
|
||||
let folderContent: Array<string>;
|
||||
let cacheDirectory: Dir;
|
||||
try {
|
||||
folderContent = await fs.promises.readdir(installFolder);
|
||||
cacheDirectory = await fs.promises.opendir(installFolder);
|
||||
} catch (error) {
|
||||
if ((error as nodeUtils.NodeError).code === `ENOENT`) {
|
||||
folderContent = [];
|
||||
return null;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const candidateVersions: Array<string> = [];
|
||||
for (const entry of folderContent) {
|
||||
const range = new semver.Range(descriptor.range);
|
||||
let bestMatch: string | null = null;
|
||||
let maxSV: semver.SemVer | undefined = undefined;
|
||||
|
||||
for await (const {name} of cacheDirectory) {
|
||||
// Some dot-folders tend to pop inside directories, especially on OSX
|
||||
if (entry.startsWith(`.`))
|
||||
if (name.startsWith(`.`))
|
||||
continue;
|
||||
|
||||
candidateVersions.push(entry);
|
||||
// If the dirname correspond to an in-range version and is not lower than
|
||||
// the previous best match (or if there is not yet a previous best match),
|
||||
// it's our new best match.
|
||||
if (range.test(name) && maxSV?.compare(name) !== 1) {
|
||||
bestMatch = name;
|
||||
maxSV = new semver.SemVer(bestMatch);
|
||||
}
|
||||
}
|
||||
|
||||
const bestMatch = semver.maxSatisfying(candidateVersions, descriptor.range);
|
||||
if (bestMatch === null)
|
||||
return null;
|
||||
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
|
|
@ -106,9 +113,7 @@ export async function installVersion(installTarget: string, locator: Locator, {s
|
|||
|
||||
stream.pipe(sendTo);
|
||||
|
||||
await new Promise(resolve => {
|
||||
sendTo.on(`finish`, resolve);
|
||||
});
|
||||
await once(sendTo, `finish`);
|
||||
|
||||
await fs.promises.mkdir(path.dirname(installFolder), {recursive: true});
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue