Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] fix: 회원가입 트랜잭션 범위 수정 & 타임아웃 시그널 수정 #257

Merged
merged 6 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<h3>동료들과 함께 소통하며 알고리즘 학습을 할 수 있는 플랫폼</h3>
<h5>🗝️ KeyWords<h5>
#WebRTC #Socket #CRDT
<p>#WebRTC #Socket #CRDT</p>
<br>
<div align="center">
<img src="https://img.shields.io/badge/node-339933?&logo=node.js&logoColor=white">
Expand Down Expand Up @@ -94,8 +94,6 @@ Pub/Sub을 활용해 다중 서버 환경에서도 채팅을 할 수 있습니
- 429 Error 및 InMemory 용량부족 해결 과정 (16만건 처리에 걸리는 시간 64% 감소)
- [도커 이미지 최적화](https://energetic-palm-634.notion.site/f35c15bc99a842a18ce095fa6bf1c806?v=efbb8ec67beb43b89792200fc1f3c9a1&pvs=4)
- 도커 이미지 사이즈 85% 감소시킨 이야기
- [서버에서 OAuth 처리하여 자원 보호하기](https://energetic-palm-634.notion.site/69f2e78273884a65b52c370debb83073?v=2b272ead31924af59732edbda24cef84&pvs=4)
- OAuth2.0을 도입하고 안전하게 자원을 관리하는 이야기

# 🔎 개발기
개발하면서 공부한 내용들과 고민 과정, 이유, 해결 방법을 기록했습니다.
Expand All @@ -112,8 +110,8 @@ Pub/Sub을 활용해 다중 서버 환경에서도 채팅을 할 수 있습니
- [Transaction 관심사 분리하기](https://energetic-palm-634.notion.site/AsyncLocalStorage-Transaction-34f42523c0ec43f4b633eb7944c0b29d?pvs=4)
- [SSL Termination을 통해 안전하게 HTTP 통신하기](https://energetic-palm-634.notion.site/SSL-Termination-HTTP-70c76949740f4452a2899fa1e617628a?pvs=4)
- [Blue-Green으로 무중단 배포하기](https://energetic-palm-634.notion.site/57396ff1e3174251ba2c7487ab070a53?pvs=4)
- [Clove X 도입하기](https://www.notion.so/Clova-Studio-d990f41d3e814b708906e64fd4707a24?pvs=4)

- [Clove X 도입하기](https://energetic-palm-634.notion.site/Clova-Studio-d990f41d3e814b708906e64fd4707a24?pvs=4)
- [서버에서 OAuth 처리하여 자원 보호하기](https://energetic-palm-634.notion.site/OAuth-2-0-2bc01496ac9c4ed6b0118642c887828d?pvs=4)

[👉 더 많은 기술정리 보러가기](https://www.notion.so/f4562ec49e0245d2b6ef203588c031ea?v=fbfeb754b1a4471e8ffc174a45c64346&pvs=4)

Expand All @@ -126,8 +124,11 @@ Pub/Sub을 활용해 다중 서버 환경에서도 채팅을 할 수 있습니
| **Front-End** | **Front-End** | **Back-End** | **Back-End** |
| [@HBSPS](https://github.com/HBSPS) | [@d0422](https://github.com/d0422) | [@HKLeeeee](https://github.com/HKLeeeee) | [@Gseungmin](https://github.com/Gseungmin) |

![AlgoITNi](https://github.com/boostcampwm2023/web05-AlgoITNi/assets/84272873/db73a539-bb3f-4cf0-af23-81e23adc6b17)


## 우리가 일하는 방식

- [그라운드 룰](https://energetic-palm-634.notion.site/1f2cbea527e341c7ad1c8fd84ed5104d?pvs=4)
- [깃 컨벤션](https://energetic-palm-634.notion.site/Git-Convention-8563596644404eb49148a940773d2be8?pvs=4)
- [게더타운 규칙](https://energetic-palm-634.notion.site/b3b67313c1f748e7b58abf99466b000b?pvs=4)
Expand Down
12 changes: 8 additions & 4 deletions backEnd/api/src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ export class AuthController {
const id_token: string = await this.googleService.getIDToken(code);
const user: UserDto = await this.googleService.getUserInfo(id_token);
let findUser = await this.userService.findUser(user);
this.logger.error(JSON.stringify(findUser));
if (findUser === null) {
await this.userService.addUser(user, 'google');
findUser = await this.userService.findUser(user);
findUser = await this.userService.getUserAfterAddUser(user, 'google');
}
this.logger.error(JSON.stringify(findUser));

const returnTo: string = await this.authService.login(findUser, res, req);
return res.redirect(returnTo);
}
Expand Down Expand Up @@ -83,10 +85,12 @@ export class AuthController {
const accessToken = await this.githubService.getGithubAccessToken(code);
const user: UserDto = await this.githubService.getUserInfo(accessToken);
let findUser = await this.userService.findUser(user);
this.logger.error(JSON.stringify(findUser));
if (findUser === null) {
await this.userService.addUser(user, 'github');
findUser = await this.userService.findUser(user);
findUser = await this.userService.getUserAfterAddUser(user, 'github');
}
this.logger.error(JSON.stringify(findUser));

const returnTo: string = await this.authService.login(findUser, res, req);

return res.redirect(returnTo);
Expand Down
31 changes: 17 additions & 14 deletions backEnd/api/src/common/transaction/transaction.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,23 @@ export class TransactionService implements OnModuleInit {
return async function (...args: any[]) {
const qr = await dataSource.createQueryRunner();

await queryRunnerLocalStorage.run({ qr }, async function () {
try {
await qr.startTransaction();
const result = await originalMethod.apply(instance, args);
await qr.commitTransaction();
return result;
} catch (e) {
await qr.rollbackTransaction();
this.logger.error(e);
throw new TransactionRollback();
} finally {
await qr.release();
}
});
const result = await queryRunnerLocalStorage.run(
{ qr },
async function () {
try {
await qr.startTransaction();
const result = await originalMethod.apply(instance, args);
await qr.commitTransaction();
return result;
} catch (e) {
await qr.rollbackTransaction();
throw new TransactionRollback();
} finally {
await qr.release();
}
},
);
return result;
};
}

Expand Down
12 changes: 11 additions & 1 deletion backEnd/api/src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@ export class UsersService {
private usersRepository: Repository<UserEntity>,
) {}
@Transactional('typeorm')
async addUser(userDTO: UserDto, oauth: OAUTH) {
async getUserAfterAddUser(
userDTO: UserDto,
oauth: OAUTH,
): Promise<UserEntity> {
const user = new UserEntity();
user.name = userDTO.name;
user.authServiceID = userDTO.authServiceID;
user.oauth = oauth;
const repository = getLocalStorageRepository(UserEntity);
await repository.save<UserEntity>(user);

const find = await repository.findOne({
where: {
authServiceID: userDTO.authServiceID,
},
});
return find as UserEntity;
}

async findUser(userDTO: UserDto): Promise<UserEntity> {
Expand Down
17 changes: 10 additions & 7 deletions backEnd/running/src/codes/codes.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export class CodesService {
process.env.NODE_ENV === 'dev'
? path.join(__dirname, '..', 'tmp')
: '/algoitni';
private killSignal: NodeJS.Signals = 'SIGINT';
private readonly killSignal: NodeJS.Signals = 'SIGINT';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수들 utils 파일에 보관하는 것도 좋아보여요!

private readonly killCode: number = 130;
private readonly timeOut = 5000;
constructor() {
if (!fs.existsSync(this.tempDir)) {
Expand All @@ -40,7 +41,6 @@ export class CodesService {
try {
fs.writeFileSync(filePath, code);
const { stdout, stderr } = await this.runCommand(filePaths, language);
this.logger.debug(`${stdout}, ${stderr}`);
if (stderr) {
throw new RunningException(stderr.trim());
}
Expand All @@ -62,7 +62,6 @@ export class CodesService {
language: supportLang,
): Promise<runCommandResult> {
const commands = languageCommand(language, filePaths);
this.logger.debug(JSON.stringify(commands));

let command;
if (commands.length > 1) {
Expand Down Expand Up @@ -99,10 +98,10 @@ export class CodesService {
this.logger.log(`child process exited with code ${code}, ${signal}`);
clearTimeout(timer);
const out = Buffer.concat(stdout).toString();
const err =
signal === this.killSignal
? Messages.TIMEOUT
: Buffer.concat(stderr).toString();
let err = Buffer.concat(stderr).toString();
if (this.isTimeout(code, signal)) {
err = Messages.TIMEOUT;
}
resolve({ stdout: out, stderr: err });
});
} catch (e) {
Expand Down Expand Up @@ -164,4 +163,8 @@ export class CodesService {
path.join(this.tempDir, `${uuid}${distExtension}`),
];
}

isTimeout(code: number, signal: NodeJS.Signals) {
return code === this.killCode || signal === this.killSignal;
}
}