Skip to content

Commit

Permalink
Merge pull request #713 from BeA-Pro/main
Browse files Browse the repository at this point in the history
[engine] Worker를 활용한 깃 로그 받아오기
  • Loading branch information
BeA-Pro authored Sep 12, 2024
2 parents f18f1d8 + b8ae0a3 commit 3b1da9c
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 5 deletions.
4 changes: 3 additions & 1 deletion packages/analysis-engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion packages/vscode/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
}
],
"simple-import-sort/exports": "error",
"no-duplicate-imports": "error"
"no-duplicate-imports": "error",
"import/no-commonjs": "off"
},
"overrides": [
{
Expand Down
11 changes: 10 additions & 1 deletion packages/vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,7 +77,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);
Expand Down
67 changes: 67 additions & 0 deletions packages/vscode/src/utils/git.util.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -154,6 +158,7 @@ export async function getGitExecutableFromPaths(paths: string[]): Promise<GitExe

export async function getGitLog(gitPath: string, currentWorkspacePath: string): Promise<string> {
return new Promise((resolve, reject) => {

const args = [
"--no-pager",
"log",
Expand Down Expand Up @@ -182,6 +187,68 @@ export async function getGitLog(gitPath: string, currentWorkspacePath: string):
});
}

export async function getLogCount(gitPath: string, currentWorkspacePath: string): Promise<number> {
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<string> {
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<string>[] = [];

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,
Expand Down
41 changes: 41 additions & 0 deletions packages/vscode/src/utils/git.worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
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(([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();
8 changes: 6 additions & 2 deletions packages/vscode/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down

0 comments on commit 3b1da9c

Please sign in to comment.