ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Coroutine] 코루틴 학습 - 2 (Under the hood)
    Java/Kotlin 2022. 4. 23. 16:58
    반응형

    Under the hood Coroutine

    • 일시중단 함수는 함수의 실행과 실행 후에도 실행 가능한 상태 머신과 같다.
    • 상태를 식별하는 번호와 로컬 데이터는 continuation 객체에 저장한다.
    • 한 함수의 Contunuation 다른 함수의 Continuation을 데코레이트 시키고, 결과적으로 모든 continuation은 다시 시작될 때 사용하는 콜스택을 나타낸다.

     

    Continuation-passing style

    • 일시중단 함수를 구현 시, Continuation은 함수에서 함수로 마지막 argument로 전달된다.
    suspend fun getUser(): User?
    suspend fun setUesr(uesr: User)
    suspend fun checkAvailability(flight: Flight): Boolean
    
    fun getUser(continuation: Continuation<*>): Any?
    fun setUser(user: User, continuation: Continuation<*>): Any
    fun checkAvailability(flight: Flight, continuation: Continuation<*>): Any
    • 일시중단 함수가 내부적으로 동작할 때, continuation이 argument로 전달되는 형태로 선언되는 것을 확인할 수 있는데, Unit과 Boolean은 Any로, User? 는 Any?로 바뀐 것을 확인할 수 있다.
      • 이는 일시중단 함수가 일시중단 되었을 때, 선언된 타입을 반환하지 않을 수 있기 때문이다.
      • 이러한 경우, COROUTINE_SUSPENDED 라는 특수한 마커 타입을 반환한다.
      • 위의 예시에서는 getUser() 함수가 User? 또는 COROUTINE_SUSPENDED를 반환한다.
    • 일시중단 함수는 두 가지 시작점에서 시작되는데, 최초로 함수가 호출되었을 경우와 일시중단 후에 재개되었을 때이다.
      • 두 상태를 식별하기 위해서 label이라는 필드를 사용한다.
      • 처음 시작되었을 때는 0이고, 일시중단 지점 앞에서 다음 상태로 변경된다. 그리고 다시 재개될 때는 일시중단 지점 앞에서 실행된다.

     

    만약 상태 값(local 변수)을 가지고 있는 함수가 일시 중단 되었을 경우에는?

    • 상태를 가지고 있는 일시중단 함수가 일시중단 되었다가 재개 되었을 때는 여전히 해당 상태를 가지고 연산을 처리할 수 있어야한다.
    • 이를 위해서 일시중단 함수는 상태값을 복원하기 위해 Continuation에 상태를 저장한다.

     

    값을 가지는 함수가 다시 재개되었을 때의 동작

    suspend fun printUser(token: String) {
        println("Before")
        val userId = getUserId(token)	// suspending
        println("Got userId: $userId")
        val userName = getUserName(userId)	// suspending
        println(User(userId, userName))
        println("After")
    }
    • 위 일시중단 함수인 printUser() 안에서 일시중단 함수인 getUserId(), getUserName()가 호출되고 있다.
    • 함수가 value로 재개되었다면, 그 결과로 Result.Success(value)를 반환한다.
    • 만약 예외로 재개되었다면, 그 결과로 Result.Failure(exception)을 반환한다.

     

    일시중단 함수에서의 콜 스택

    • 일시중단 함수는 일시중단되면 쓰레드를 반환하고, 그 결과로 콜스택을 클리어한다.
    • 콜스택의 기능을 제공하기 위해 각 Continuation들은 중단되었을 때의 상태(지역변수와 파라미터 등)와 호출된 continuation 참조들을 저장해둔다. 즉, 하나의 continuation이 다른 continuation을 참조하고, 다른 continuation이 또 다른 continuation을 참조하는 것이다.
    • 일반적인 콜스택과 일시중단 함수가 제공하는 콜스택 도식도는 아래와 같다.

     


    참고자료

    https://www.amazon.com/Kotlin-Coroutines-Deep-Marcin-Moskala/dp/8396395837

     

    반응형

    댓글

Designed by Tistory.