From 64a04da56bc8bfced7f7fd05e90769b989871932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bengt=20Wei=C3=9Fe?= Date: Fri, 12 Jul 2024 08:44:09 +0200 Subject: [PATCH 1/3] fix: try to decrease parallel file operations while signing --- src/util.ts | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/src/util.ts b/src/util.ts index 00dc1c8..aa61ad3 100644 --- a/src/util.ts +++ b/src/util.ts @@ -84,16 +84,6 @@ export async function detectElectronPlatform (opts: BaseSignOptions): Promise { debugLog('Walking... ' + dirPath); - async function _walkAsync (dirPath: string): Promise> { + async function _walkAsync (dirPath: string): Promise { const children = await fs.readdir(dirPath); - return await Promise.all( + const binaryFiles: string[] = []; + const filesToCheck: string[] = []; + const filesToRemove: string[] = []; + const foldersToCheck: string[] = []; + + await Promise.all( children.map(async (child) => { const filePath = path.resolve(dirPath, child); @@ -146,24 +141,38 @@ export async function walkAsync (dirPath: string): Promise { if (stat.isFile()) { switch (path.extname(filePath)) { case '.cstemp': // Temporary file generated from past codesign - debugLog('Removing... ' + filePath); - await fs.remove(filePath); - return null; + filesToRemove.push(filePath); + break; default: - return await getFilePathIfBinary(filePath); + filesToCheck.push(filePath); } } else if (stat.isDirectory() && !stat.isSymbolicLink()) { - const walkResult = await _walkAsync(filePath); + foldersToCheck.push(filePath); switch (path.extname(filePath)) { case '.app': // Application case '.framework': // Framework - walkResult.push(filePath); + binaryFiles.push(filePath); } - return walkResult; } - return null; }) ); + + await Promise.all(filesToRemove.map(async (filePath) => { + debugLog(`Removing... ${filePath}`); + await fs.remove(filePath); + })); + + for (const filePath of filesToCheck) { + if (await isBinaryFile(filePath)) { + binaryFiles.push(filePath); + } + } + + for (const folderPath of foldersToCheck) { + binaryFiles.push(...(await _walkAsync(folderPath))); + } + + return binaryFiles; } const allPaths = await _walkAsync(dirPath); From e8ba7697a74f86e1203f4eb43f37459f5f98943e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bengt=20Wei=C3=9Fe?= Date: Fri, 12 Jul 2024 09:25:44 +0200 Subject: [PATCH 2/3] fix: comments + filesToCheck in chunks --- src/util.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/util.ts b/src/util.ts index aa61ad3..cbe5241 100644 --- a/src/util.ts +++ b/src/util.ts @@ -128,6 +128,7 @@ export async function walkAsync (dirPath: string): Promise { async function _walkAsync (dirPath: string): Promise { const children = await fs.readdir(dirPath); + const binaryFiles: string[] = []; const filesToCheck: string[] = []; const filesToRemove: string[] = []; @@ -148,6 +149,7 @@ export async function walkAsync (dirPath: string): Promise { } } else if (stat.isDirectory() && !stat.isSymbolicLink()) { foldersToCheck.push(filePath); + switch (path.extname(filePath)) { case '.app': // Application case '.framework': // Framework @@ -157,17 +159,23 @@ export async function walkAsync (dirPath: string): Promise { }) ); + // Remove all old tmp files -> should be not much per folder recursion await Promise.all(filesToRemove.map(async (filePath) => { debugLog(`Removing... ${filePath}`); await fs.remove(filePath); })); - for (const filePath of filesToCheck) { - if (await isBinaryFile(filePath)) { - binaryFiles.push(filePath); - } + // Only binaries need to be signed + // isBinaryFile method opens file, calls stat and alloc 1KB memory and reads in file + // build chunks of 10 files to avoid reaching memory or open file handle limits + const chunkSize = 10; + for (let index = 0; index < filesToCheck.length; index += chunkSize) { + await Promise.all(filesToCheck.slice(index, index + chunkSize).map( + async (filePath) => await isBinaryFile(filePath) && binaryFiles.push(filePath)) + ); } + // Do avoid fast and easy memory or open file handle bail outs trigger recursion not in parallel for (const folderPath of foldersToCheck) { binaryFiles.push(...(await _walkAsync(folderPath))); } From 8e24a381834ea43267958516ebdba2df91a212d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bengt=20Wei=C3=9Fe?= Date: Fri, 12 Jul 2024 09:28:34 +0200 Subject: [PATCH 3/3] refactor: no need for flatten --- src/util.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/util.ts b/src/util.ts index cbe5241..7fd1217 100644 --- a/src/util.ts +++ b/src/util.ts @@ -183,6 +183,5 @@ export async function walkAsync (dirPath: string): Promise { return binaryFiles; } - const allPaths = await _walkAsync(dirPath); - return compactFlattenedList(allPaths); + return await _walkAsync(dirPath); }