deleteAllUserInfo = async (req, res, next) => {
const userId = res.locals.user;
const { adminVerification } = req.body;
const confirmRequest = req.confirmRequest;
const maxListeners = 5; // 임계값 설정
const timeoutDuration = 15 * 1000; // 15초
let totalDeletedCount = 0;
const timeoutFunc = (listener) => {
return setTimeout(() => {
confirmRequest.off('requestCompleted', listener);
// 이벤트 리스너 제거
throw new CustomError("요청이 너무 오래 걸립니다.", 408)
}, timeoutDuration);
};
const processDelete = async () => {
console.log("현재 처리 중 요청 갯수 : ", confirmRequest.getCurrentRequests());
if (confirmRequest.getCurrentRequests() > 5) {
if (confirmRequest.listenerCount('requestCompleted') >= maxListeners) {
throw new CustomError("동시 삭제 시도 횟수가 너무 많습니다.", 404);
}
const listener = () => {
clearTimeout(timeout); // 타임아웃 제거
confirmRequest.off('requestCompleted', listener);
// 이벤트 리스너 제거
processDelete();
};
const timeout = timeoutFunc(listener);
confirmRequest.once('requestCompleted', listener);
return;
}
// 5개의 데이터를 삭제
const deletedCount = await this.userInfoService.deleteAllUserInfo(userId, adminVerification);
// 삭제된 데이터 수를 누적
totalDeletedCount += deletedCount;
// 삭제된 데이터 수가 5개 미만이면 종료
if (deletedCount < 5) {
return res.status(200).json({ message: `총 ${totalDeletedCount}개의 회원 정보 삭제 작업이 완료되었습니다.` });
}
// 계속 삭제 처리
processDelete();
};
await processDelete();
}
이것도 역시 완성된 코드라 내용이 많은데 이벤트에 대해서 이해하는 게 가장 어려웠다. 이벤트를 기존에 사용하던 함수처럼 생각을 해서 위에서부터 순서대로 실행이 된다고 생각해서 어떻게 리스너가 실행되는지 그리고 재귀 함수가 종료되는지 이해할 수 없었다. off나 once가 바로 실행되는 것인 줄 알았다. 그래도 계속 보고 고민하다 보니까 이벤트가 기존 함수처럼 알아서 실행되는 게 아니라 내가 설정한 이벤트가 발생해야 리스터가 실행되는 것이란 것을 알게 되었다.
- 함수 정의
- await 함수 호출
- 조건문 판단
- listener 정의 (실행x)
- listener 등록 ( 이벤트 발생 전까지 실행 x )
- 다음 줄로 넘어감 6. return (함수 종료)
- 실행 중이던 요청이 완료됨 (requestCompleted 이벤트 발생)
- 등록했던 listener 실행
- confirmRequest.off('requestCompleted', listener); 리스너 제거 (이건 이벤트 시점 안기다림)
- 함수 호출 (재귀)
이렇게 이해할 수 있었다. 그리고 이후에 추가적인 보완을 했다
- 이벤트가 실행이 안된다면 계속 대기하는 상태가 유지되는 문제가 있다.
- 중간에 함수를 반환하는 return이 있지만 그래도 삭제 요청이 너무 많이 쌓이는 문제가 생길 수도 있으니 삭제 요청이 쌓이면 에러를 발생시켜 실행을 중단시키는 게 좋다.
- 최초 함수를 실행 시킬 때 함수 내부의 로직이 끝나기 전에 결괏값을 반환할 수도 있다. 그래서 await를 추가해서 함수 내부의 처리가 다 완료될 때까지 기다리게 한다.
그리고 시퀄라이즈에서 지원하는 소프트 딜르트와 훅 기능을 이용해서 회원 탈퇴 전에 탈퇴할 회원의 게시물을 남기기 위해 지정된 유저 데이터를 이용해 기본 프로필 사진과 정해진 닉네임으로 변경되게 하였으며, 자동 실행 기능은 후순위로 두고 일단은 회원 탈퇴 로직을 마무리할 수 있었다. 글로 정리하니까 짧은데 이벤트라는 게 왜 저렇게 되는 건지 이해하는데 힘들었다.
'오늘 뭐했냐 > 함께했던 작업들' 카테고리의 다른 글
23.08.30 회원탈퇴4 (스케줄러 적용) (0) | 2023.09.07 |
---|---|
23.08.28 이미지 업로드 속도 문제 (0) | 2023.09.05 |
23.08.26 회원 탈퇴 만들기2 (서버 상태 확인 모듈 만들기) (0) | 2023.09.03 |
23.08.25 회원 탈퇴 만들기 1 (기획) (0) | 2023.09.03 |
23.08.23 리프레시 토큰 (Refresh Token) (0) | 2023.09.02 |