Skip to content

Commit

Permalink
feat: fs access (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
elrrrrrrr authored Oct 23, 2023
1 parent fa88553 commit 1a77921
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 12 deletions.
11 changes: 7 additions & 4 deletions packages/cli/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ exports.install = async options => {

const allPkgs = await util.getAllPkgPaths(options.cwd, options.pkg);

await Promise.all(allPkgs.map(async pkgPath => {
for (const pkgPath of allPkgs) {
const { baseDir, tarIndex, nodeModulesDir } = await util.getWorkdir(options.cwd, pkgPath);

const mountedInfo = currentMountInfo.find(item => item.mountPoint === nodeModulesDir);

if (mountedInfo) {
console.log(`[rapid] ${nodeModulesDir} already mounted, try to clean`);
await exports.clean(path.join(options.cwd, pkgPath));
await exports.clean(path.join(options.cwd, pkgPath), true);
}

await fs.mkdir(baseDir, { recursive: true });
await fs.mkdir(path.dirname(tarIndex), { recursive: true });
}));
}

await fs.mkdir(tarBucketsDir, { recursive: true });
await util.createNydusdConfigFile(nydusdConfigFile);
Expand All @@ -58,7 +58,10 @@ exports.install = async options => {
assert(Object.keys(packageLock).length, '[rapid] depsJSON invalid.');
await nydusd.startNydusFs(nydusMode, options.cwd, options.pkg);

// 执行 lifecycle scripts
console.time('[rapid] wait for access');
await util.ensureAccess(options.cwd, packageLock);
console.timeEnd('[rapid] wait for access');

console.time('[rapid] run lifecycle scripts');
await options.scripts.runLifecycleScripts(mirrorConfig);
console.timeEnd('[rapid] run lifecycle scripts');
Expand Down
18 changes: 10 additions & 8 deletions packages/cli/lib/nydusd/fuse_mode.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,19 @@ async function generateBootstrapFile(cwd, pkg) {

async function mountNydus(cwd, pkg) {
const allPkgs = await getAllPkgPaths(cwd, pkg);
await Promise.all(allPkgs.map(async pkgPath => {

// 需要串行 mount,并发创建时 nydusd 会出现问题
for (const pkgPath of allPkgs) {
const { dirname, bootstrap } = await getWorkdir(cwd, pkgPath);
console.time(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`);
await nydusdApi.mount(`/${dirname}`, cwd, bootstrap);
console.timeEnd(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`);
}));
}
}

async function mountOverlay(cwd, pkg) {
const allPkgs = await getAllPkgPaths(cwd, pkg);
await Promise.all(allPkgs.map(async pkgPath => {
for (const pkgPath of allPkgs) {

const {
upper,
Expand Down Expand Up @@ -90,15 +92,15 @@ ${upper}=RW:${mnt}=RO \
${nodeModulesDir}`;
}
console.info('[rapid] mountOverlay: `%s`', shScript);
console.time('[rapid] overlay mounted.');
await execa.command(shScript);
console.info('[rapid] overlay mounted.');
}));
console.timeEnd('[rapid] overlay mounted.');
}
}

async function endNydusFs(cwd, pkg) {
const allPkgs = await getAllPkgPaths(cwd, pkg);
await Promise.all(allPkgs.map(async pkgPath => {

for (const pkgPath of allPkgs) {
const {
dirname,
overlay,
Expand All @@ -117,7 +119,7 @@ async function endNydusFs(cwd, pkg) {
await nydusdApi.umount(`/${dirname}`);
// 清除 nydus 相关目录
await fs.rm(baseDir, { recursive: true, force: true });
}));
}
}

module.exports = {
Expand Down
37 changes: 37 additions & 0 deletions packages/cli/lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,43 @@ function validDep(pkg, productionMode, arch, platform) {

}

exports.ensureAccess = async function ensureAccess(cwd, packageLock) {
let access = false;
let targetPath;

for (const [ pkgPath, pkgItem ] of Object.entries(packageLock)) {
if (pkgPath.startsWith('node_modules') && !pkgItem.optional) {
targetPath = pkgPath;
break;
}
}

// 如果没有找到合适的检测点,直接返回
if (!targetPath) {
return;
}

let retry = 0;

// 如果找到了检测点,但是检测点不存在,等待检测点创建
while (!access) {
try {
await fs.access(targetPath);
access = true;
} catch (e) {
retry++;
console.log(
`[rapid] still waiting for access ${targetPath} retry after 50ms, retry count: ${retry}`
);
if (retry > 40) {
console.error(`[rapid] wait for access ${targetPath} timeout`);
throw e;
}
await this.sleep(50);
}
}
};

exports.getAllPkgPaths = async function getAllPkgPaths(cwd, pkg) {
const workspaces = await exports.getWorkspaces(cwd, pkg);
const allPkgs = Object.values(workspaces);
Expand Down

0 comments on commit 1a77921

Please sign in to comment.