ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kotlin Coroutines 톺아보기
    세미나, 영상 요약정리 2022. 12. 28. 00:01

    https://www.youtube.com/watch?v=eJF60hcz3EU 

     

    당근마켓 로컬 커머스팀의 김태우님의 Kotlin Coroutines 톺아보기를 보고 요약한 내용입니다.

     

    동기

    그림 1

    [그림 1]은 동기적으로 실행되는 코드입니다.

     

    비동기로 변환

    그림 2

    [그림 2]은 비동기 코드입니다.

    한번에 이해하기 힘들며 추적이 어렵고, 에러 핸들링이 어렵습니다.

     

    다양한 비동기 라이브러리

    또한 다양한 비동기 라이브러리가 존재하며 어떤 것을 사용해야 할지, 혼용해서 사용하기 위해서는 어떻게 사용해야 할지, 또 다른 비동기 라이브러리가 추가된다면 어떻게 해야 할지 고민하게 됩니다.

     

    rxjava3의 Maybe

    jdk9의 Flow

    reactor의 Flux

    mutiny의 Multi

    jdk8의 CompletableFuture

     

     

    이런 다양한 비동기 방식을 조합하게 되면 [그림 2]처럼 subscribe hell이 됩니다.

    javascript의 callback hell과 유사합니다.

     

    각각의 비동기 방식을 조합하지 않고 Reactor만 사용하더라도 똑같이 flatMap hell이 됩니다.

     

     

     

    코루틴

    이런 고민들을 해결하기 위해 코루틴을 사용하고자 했습니다.

    그림 3

    [그림 3]는 [그림 2]과 똑같은 역할을 하는 코드입니다.

    하지만 코루틴을 통해 가독성을 높이고, 에러 헨들링, 동시성 처리 등 다양한 이점들을 가집니다.

     

    코루틴은 suspend 키워드를 통해 동기 코드[그림와 굉장히 유사한 모습을 보여줍니다.

     

     

    Coroutine 톺아보기

    awaitSingle, suspend 등이 어떤 것을 의미할까요?

     

    주변에 코루틴에 대해 물어보면 다음과 같은 대답을 받을 수 있습니다.

    - 경량화된 쓰레드

    - 특정 지점에서 정지했다가 재개할 수 있는 쓰레드

     

     

    FSM 기반의 재귀 함수

    코루틴은 Finite State Machine 기반의 재귀 함수로 변환됩니다.

     

    Kotlin 컴파일러가 suspend가 붙은 함수에 추가적인 코드를 추가합니다.

    - Continuation 인자를 타겟 함수에 추가하고 구현체를 생성

    - 타켓 함수 내의 모든 suspend 함수에 생성한 continuation 객체를 패스
    - 코드를 분리해서 switch case 안에 넣고 label을 이용해서 state 변경

     

    FSM 기반의 동기 코드로

    그림 4

    - SharedData를 통해서 여러 가지 context를 저장

    - label은 state machine의 현재 state 값

    - 이전 state에서 찾은 값들을 buyer, address, products, stores, order에 저장

    - resumeWith로 재귀 호출을 하고 결과를 reulst에 저장

    - 인자의 sharedData가 null이라면 생성하고 아니면 있는 sharedData를 사용

     

     

    State Machine으로 변환

    그림 5

    가장 먼저 state =0 이므로 0 -> 부분이 실행되며 shared.label = 1으로 변환합니다.

    이후 재귀 함수를 호출합니다.

     

    다음에는 state =1 이므로 1-> 부분이 실행되며 shared.label = 2로 변환합니다.

    이후 재귀함수를 호출합니다.

     

    마지막 state=5 일 때는 재귀 함수를 호출하지 않고 값을 반환합니다.

     

    FSM 기반의 비동기 코드로

    그림 6

     

    FSM 기반의 비동기 코드

    그림 7

    - sharedData -> Continutation

    - subscribe를 활용

     

    위 두 가지를 제외하고는 동기 코드와 유사합니다.

     

    FSM 기반의 Coroutine  : 확장 함수를 활용

    코루틴은 확장 함수를 지원합니다.

    그림 8

    [그림 8]은 코루틴의 확장 함수를 적용한 모습입니다.

     

    코루틴 컴파일러는 when을 만들고 각각을 쪼개는 역할을 수행합니다.

    그림 9

    [그림 9]는 when을 제거한 모습입니다.

     

    코틀린 컴파일러는 Continuation을 만들고 인자를 넣어줍니다.

     

     

    이제 최종 버전입니다.

    그림 10

    이제 처음 보았던 코루틴을 활용한 코드[그림 3]와 유사함을 알 수 있십니다.

     

    댓글

Designed by Tistory.