From 2f913fb0ab48c849b6b07317e4b1b6a2c383dd4a Mon Sep 17 00:00:00 2001 From: YongHyunKing Date: Mon, 9 Sep 2024 02:43:12 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=EB=A9=80=ED=8B=B0=EC=93=B0?= =?UTF-8?q?=EB=A0=88=EB=93=9C=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/analysis-engine/src/index.ts | 4 +- packages/vscode/.eslintrc.json | 3 +- packages/vscode/src/extension.ts | 11 +++- packages/vscode/src/utils/git.util.ts | 67 +++++++++++++++++++++++++ packages/vscode/src/utils/git.worker.ts | 58 +++++++++++++++++++++ packages/vscode/webpack.config.js | 8 ++- 6 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 packages/vscode/src/utils/git.worker.ts diff --git a/packages/analysis-engine/src/index.ts b/packages/analysis-engine/src/index.ts index f6de204b..a54ab75d 100644 --- a/packages/analysis-engine/src/index.ts +++ b/packages/analysis-engine/src/index.ts @@ -53,7 +53,9 @@ export class AnalysisEngine { if (this.isDebugMode) console.log("baseBranchName: ", this.baseBranchName); const commitRaws = getCommitRaws(this.gitLog); - if (this.isDebugMode) console.log("commitRaws: ", commitRaws); + if (this.isDebugMode){ + console.log("commitRaws: ", commitRaws); + } const commitDict = buildCommitDict(commitRaws); if (this.isDebugMode) console.log("commitDict: ", commitDict); diff --git a/packages/vscode/.eslintrc.json b/packages/vscode/.eslintrc.json index 093a13f7..25d2a036 100644 --- a/packages/vscode/.eslintrc.json +++ b/packages/vscode/.eslintrc.json @@ -12,7 +12,8 @@ } ], "simple-import-sort/exports": "error", - "no-duplicate-imports": "error" + "no-duplicate-imports": "error", + "import/no-commonjs": "off" }, "overrides": [ { diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts index a046b354..149b9dc4 100644 --- a/packages/vscode/src/extension.ts +++ b/packages/vscode/src/extension.ts @@ -7,6 +7,7 @@ import { GithubTokenUndefinedError, WorkspacePathUndefinedError } from "./errors import { deleteGithubToken, getGithubToken, setGithubToken } from "./setting-repository"; import { mapClusterNodesFrom } from "./utils/csm.mapper"; import { + fetchGitLogInParallel, findGit, getBranches, getCurrentBranchName, @@ -74,7 +75,15 @@ export async function activate(context: vscode.ExtensionContext) { const initialBaseBranchName = await fetchCurrentBranch(); const fetchClusterNodes = async (baseBranchName = initialBaseBranchName) => { - const gitLog = await getGitLog(gitPath, currentWorkspacePath); + console.time('Multi log') + const gitLog = await fetchGitLogInParallel(gitPath, currentWorkspacePath); + console.timeEnd('Multi log') + + // console.time('Single log') + // const testGitLog = await getGitLog(gitPath, currentWorkspacePath); + // console.timeEnd('Single log') + + const gitConfig = await getGitConfig(gitPath, currentWorkspacePath, "origin"); const { owner, repo: initialRepo } = getRepo(gitConfig); webLoader.setGlobalOwnerAndRepo(owner, initialRepo); diff --git a/packages/vscode/src/utils/git.util.ts b/packages/vscode/src/utils/git.util.ts index 25a4ab22..a5998c87 100644 --- a/packages/vscode/src/utils/git.util.ts +++ b/packages/vscode/src/utils/git.util.ts @@ -1,6 +1,10 @@ import * as cp from "child_process"; import * as fs from "fs"; +import os from 'os'; import * as path from "path"; +import { Worker } from 'worker_threads'; + + export interface GitExecutable { readonly path: string; @@ -154,6 +158,7 @@ export async function getGitExecutableFromPaths(paths: string[]): Promise { return new Promise((resolve, reject) => { + const args = [ "--no-pager", "log", @@ -182,6 +187,68 @@ export async function getGitLog(gitPath: string, currentWorkspacePath: string): }); } +export async function getLogCount(gitPath: string, currentWorkspacePath: string): Promise { + return new Promise((resolve, reject) => { + const args = [ + "rev-list", + "--count", + "--all", + ]; + + resolveSpawnOutput( + cp.spawn(gitPath, args, { + cwd: currentWorkspacePath, + env: Object.assign({}, process.env), + }) + ).then(([status, stdout, stderr]) => { + const { code, error } = status; + + if (code === 0 && !error) { + const commitCount = parseInt(stdout.toString().trim(), 10); // Buffer를 문자열로 변환 후 숫자로 변환 + resolve(commitCount); // 숫자를 반환 + } else { + reject(stderr); + } + }); + }); +} + + +export async function fetchGitLogInParallel(gitPath: string, currentWorkspacePath: string): Promise { + const numCores = os.cpus().length; + const numberOfThreads = Math.max(1, numCores - 1) + const totalCnt = await getLogCount(gitPath, currentWorkspacePath); + console.log("total logs", totalCnt); + const chunkSize = Math.ceil(totalCnt/ numberOfThreads); + const promises: Promise[] = []; + + for (let i = 0; i < numberOfThreads; i++) { + const skipCount = i * chunkSize; + const limitCount = chunkSize; + + console.log('__dirname:', __dirname); + const worker = new Worker(path.resolve(__dirname, './worker.js'), { + workerData: { + gitPath, + currentWorkspacePath, + skipCount, + limitCount, + }, + }); + + promises.push( + new Promise((resolve, reject) => { + worker.on('message', resolve); + worker.on('error', reject); + }) + ); + } + + return Promise.all(promises).then((logs) => logs.join('\n')); +} + + + export async function getGitConfig( gitPath: string, currentWorkspacePath: string, diff --git a/packages/vscode/src/utils/git.worker.ts b/packages/vscode/src/utils/git.worker.ts new file mode 100644 index 00000000..1d011290 --- /dev/null +++ b/packages/vscode/src/utils/git.worker.ts @@ -0,0 +1,58 @@ +import * as cp from 'child_process'; +import { parentPort, workerData } from 'worker_threads'; + +import { resolveSpawnOutput } from './git.util' + +const { gitPath, currentWorkspacePath, skipCount, limitCount } = workerData; + +async function getPartialGitLog() { + const args = [ + '--no-pager', + 'log', + '--all', + '--parents', + '--numstat', + '--date-order', + '--pretty=fuller', + '--decorate', + '-c', + `--skip=${skipCount}`, + `-n ${limitCount}`, + ]; + + + // resolveSpawnOutput( + // cp.spawn(gitPath, args, { + // cwd: currentWorkspacePath, + // env: Object.assign({}, process.env), + // }) + // ).then((values) => { + // const [status, stdout, stderr] = values; + // if (status === 0 && parentPort !== null) { + // parentPort.postMessage(stdout.toString()); + // } else { + // if (parentPort !== null) parentPort.postMessage(stderr); + // } + // }).catch(error => { + // console.error('Spawn Error:', error); + // }); + + resolveSpawnOutput( + cp.spawn(gitPath, args, { + cwd: currentWorkspacePath, + env: Object.assign({}, process.env), + }) + ).then(([status, stdout, stderr]) => { + const { code, error } = status; + + if (code === 0 && !error && parentPort !== null) { + parentPort.postMessage(stdout.toString()); + } else { + if (parentPort !== null) parentPort.postMessage(stderr); + } + }).catch(error => { + console.error('Spawn Error:', error); + }); +} + +getPartialGitLog(); \ No newline at end of file diff --git a/packages/vscode/webpack.config.js b/packages/vscode/webpack.config.js index 80a33728..85a4fbac 100644 --- a/packages/vscode/webpack.config.js +++ b/packages/vscode/webpack.config.js @@ -12,11 +12,15 @@ const extensionConfig = { target: "node", // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/ mode: "none", // this leaves the source code as close as possible to the original (when packaging we set this to 'production') - entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ + entry: { + extension: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/ + worker: "./src/utils/git.worker.ts" + }, output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ path: path.resolve(__dirname, "dist"), - filename: "extension.js", + // filename: "extension.js", + filename: "[name].js", libraryTarget: "commonjs2", }, externals: { From b8ae0a378b31dbfd2101227f7af881dd5c153113 Mon Sep 17 00:00:00 2001 From: YongHyunKing Date: Mon, 9 Sep 2024 02:49:31 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20git.helper=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/vscode/src/utils/git.worker.ts | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/packages/vscode/src/utils/git.worker.ts b/packages/vscode/src/utils/git.worker.ts index 1d011290..4a3f9a49 100644 --- a/packages/vscode/src/utils/git.worker.ts +++ b/packages/vscode/src/utils/git.worker.ts @@ -20,23 +20,6 @@ async function getPartialGitLog() { `-n ${limitCount}`, ]; - - // resolveSpawnOutput( - // cp.spawn(gitPath, args, { - // cwd: currentWorkspacePath, - // env: Object.assign({}, process.env), - // }) - // ).then((values) => { - // const [status, stdout, stderr] = values; - // if (status === 0 && parentPort !== null) { - // parentPort.postMessage(stdout.toString()); - // } else { - // if (parentPort !== null) parentPort.postMessage(stderr); - // } - // }).catch(error => { - // console.error('Spawn Error:', error); - // }); - resolveSpawnOutput( cp.spawn(gitPath, args, { cwd: currentWorkspacePath,