Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
📌 관련 이슈
🛠️ 작업 내용
🎯 리뷰 포인트
비동기를 도입한 이유
저희 서비스에는 게임중 읽은 쪽지들을 게임이 끝난 후 보여주는 기능이 있습니다.
그래서 내부동작이
쪽지를 읽는다 → 읽은쪽지로그에 해당 쪽지가 있는지 검증한다 → 없으면 읽은쪽지로그 테이블에 저장한다 → 이로직이 끝난후 쪽지를 보여준다
이 순서로 동작이 일어납니다.
만약 읽은쪽지로그 테이블의 데이터가 많이 쌓인다면 사용자는 쪽지 하나를 읽기 위해서 읽은쪽지로그를 모두 찾고 저장하는 동작이 끝날때가지 요청을 기다려야합니다.
저는 쪽지를 읽는 행위를 하는 것은 그 행위만 하도록 하고 싶었습니다. 중복제거를 위해 쪽지가 있는지 확인하는 동작, 읽은쪽지로그 테이블에 저장하는 동작까지 쪽지를 읽는 행위에 포함되는것이 맞지 않다고 생각했습니다.
먼저 주기능과 부 기능을 분리하기 위해서 트렌젝션을 분리해야 한다고 생각했습니다.
부기능 함수에 *
@Transactional*(propagation = Propagation.REQUIRES_NEW)
이 어노테이션을 달아주었습니다. 하지만 저 어노테이션만으로는 스레드 분리가 되지 않기때문에 부 기능에서 예외가 발생하면 주기능까지 전파되는것이 해결되지 않았고, 스레드가 분리되지 않는 이상 결국 부기능을 주기능이 기다려야 했습니다.
그래서 비동기로 스레드를 분리해야겠다고 생각했습니다.
비동기로 스레드를 분리하면 주기능과 부기능이 완전히 분리가 되었고 트렌젝션도 별도로 진행되었습니다.
비동기 여정
1. 비동기 처리를 위한 조건
참고 블로그 : [https://velog.io/@gillog/Spring-Async-Annotation비동기-메소드-사용하기](https://velog.io/@gillog/Spring-Async-Annotation%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)
위 조건을 만족하기위해
LetterLogService
를 분리하게 되었습니다.2. 비동기 예외처리
비동기 함수는 메인스레드의 작업이 아니기 때문에
ExceptionHandler
가 잡아주지 못하고, 따로 처리해아합니다. 그래서AsyncExceptionHandler
를 구현하게 되었습니다.하지만
handleUncaughtException
는 로그를 찍을 수는 있지만 클라이언트에게 예외를 보여주지는 못하는것 같습니다 (문제점이라고 생각..)비동기 테스트 하기
비동기 함수를 테스트 하는것이 매우 까다로웠습니다. 이유는 테스트 함수도 하나의 스레드이기 때문에 비동기 함수가 비동기로 실행이 되면 비동기 함수가 끝나기전에 테스트가 끝나버리는 문제가 발생했습니다.
CountDownLatch, CompletableFuture 등 다양한 방법을 시도했으나 저희이 비동기 함수는 void였고 생각보다 많이 까다로워서 잘 해결되지 않았습니다.
결국 제가 해결한 방법은 비동기 함수가 실행되는 스레드를 빈으로 등록하고 빈 이름을 "asyncExecutor" 로 정해주었습니다.
그리고 테스트 실행시 빈을 초기화 할때
"asyncExecutor" 라는 빈이 등록될 시 해당 빈을 동기로 실행하는 로직을 추가해주었습니다.
참고 블로그: [https://velog.io/@byeongju/비동기-로직-동기-방식으로-테스트하기](https://velog.io/@byeongju/%EB%B9%84%EB%8F%99%EA%B8%B0-%EB%A1%9C%EC%A7%81-%EB%8F%99%EA%B8%B0-%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C-%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%98%EA%B8%B0)
하지만 비동기 함수에서 발생하는 예외는 예외를 던지지않고 로그만 찍기 때문에 따로 테스트할 방안을 찾지 못하여서 해당 테스트는 일단 주석처리 해놓았습니다..
⏳ 작업 시간
추정 시간: 8시간
실제 시간: 48시간
비동기 처리할때 고려할 사항이 생각보다 너무 많았어서 산넘어 산이었네요..