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

[Bug]: 비동기 스케쥴링 간 레이스 컨디션 #41

Closed
h-beeen opened this issue Nov 26, 2024 · 1 comment · Fixed by #44
Closed

[Bug]: 비동기 스케쥴링 간 레이스 컨디션 #41

h-beeen opened this issue Nov 26, 2024 · 1 comment · Fixed by #44
Assignees
Labels
bug Something isn't working

Comments

@h-beeen
Copy link
Member

h-beeen commented Nov 26, 2024

Bug description

현재 구현

    private final ScheduledExecutorService scheduler;
    private final Executor virtualThreadExecutor;

문제점 :

  • I/O 작업을 일정 간격으로 비동기 실행하기 위한 방법으로, ScheduledExecutorService 구현체를 통해,
    0.7초 간격으로 비동기 호출하는 로직
  • 스케쥴러가 이전 작업을 0.7초 간격으로 스케쥴링 하는 중, 새로운 작업이 요청되면 기존 작업과 레이스컨디션이 발생해,
    Lock에 의해 스케쥴러가 RejectedExecutionException을 맞딱뜨리게 됨
  • 비관적 락으로 인해 스케줄러가 직렬화되어 있어서 새로운 요청이 계속적으로 스케쥴링을 대기하는 상태

Expected behavior

AS-IS

  • Case 1. 현 개선안
    requestMultipleProduct(3건) -> 3건을 0.7초 간격으로 I/O 요청
    requestMultipleProduct(5건) -> 3건의 I/O 요청이 모두 끝난 뒤, 5건을 0.7초 간격으로 I/O 요청

  • Case 2. HotFix 개선안
    requestMultipleProduct(3건) -> 3건을 0.7초 간격으로 I/O 요청
    requestMultipleProduct(5건) -> 3건의 I/O 요청이 모두 끝난 뒤 [Not Callback] , 5건을 0.7초 간격으로 I/O 요청
    requestMultipleProduct(10건) -> 8건의 I/O 요청이 모두 끝난 뒤, 10건을 0.7초 간격으로 I/O 요청

-> 스케쥴러 자체를 비관적 Lock으로 구현하면서 요청이 많아질 때 요청 스케쥴링 자체가 지연.

TO-BE

requestMultipleProduct(3건) -> 3건을 0.7초 간격으로 I/O 요청
requestMultipleProduct(5건) -> 위 요청건을 진행하는 것과 별도의 비동기로 5건을 0.7초 간격으로 I/O 요청

To Reproduce

  1. Reactor의 Flux 사용
  • WebFlux와 연동성 향상. But 너무 무거운 SDK로 발전
  1. ScheduledExecutorService + BlockingQueue
BlockingQueue<EasyCodefRequest> queue = new LinkedBlockingQueue<>(requests);
scheduler.scheduleAtFixedRate(
    () -> {
        EasyCodefRequest request = queue.poll();
        if (request != null) {
            executeRequest(request);
        }
    },
    0, 700, TimeUnit.MILLISECONDS
);
  1. Kotlin + Coroutine

Possible Solution

No response

etc.

No response

@h-beeen h-beeen added the bug Something isn't working label Nov 26, 2024
@h-beeen h-beeen changed the title [Bug]: 가상 쓰레드 풀 [Bug]: 가상 쓰레드 풀 조정 Nov 26, 2024
@h-beeen h-beeen changed the title [Bug]: 가상 쓰레드 풀 조정 [Bug]: 비동기 스케쥴링 간 레이스 컨디션 Nov 27, 2024
@h-beeen
Copy link
Member Author

h-beeen commented Nov 27, 2024

[ 가상 스레드 적용 시의 주의 사항 ]
따라서 JVM 개발자가 직접 다음의 가상 스레드 도입 가이드를 제안하였다.

간단한 blocking/synchronous 코드로 넘어가기
플랫폼 스레드를 가상 스레드로 바꾸는 것이 아니라 태스크(Task)를 가상 스레드로 바꾸기
동시성 제한을 위해 스레드 풀이 아닌 세마포어와 같은 기술을 사용하기
스레드 로컬에 무거운 객체를 캐시하지 않기

출처: https://mangkyu.tistory.com/317 [MangKyu's Diary:티스토리]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

1 participant