인프런 커뮤니티 질문&답변

xeroman님의 프로필 이미지
xeroman

작성한 질문수

2시간으로 끝내는 코루틴

6강. Structured Concurrency

completing의 존재의의가 궁금합니다.

작성

·

67

·

수정됨

1

안녕하세요? 강의 정말 잘 듣고 있습니다. 세심한 답변도 감사드립니다.

강의를 듣던중 궁금증이 생겼는데요,

completing이라는 status의 의의가 좀 궁금합니다.

 

강의예시로 보여주신 코드는 대략 아래와 같은 느낌이였는데요, 이경우 두번째 자식 코루틴 취소 -> 부모로 전파 -> 다른 자식으로 전파(취소요청) -> 취소 된다는 부분은 이해했습니다.

fun main(): Unit = runBlocking {
    launch {
        delay(700L)
        printWithThread("First Child Corutine")
    }
    launch {
        delay(500L)
        throw IllegalArgumentException("Second Child Corutine Exception~~~!")
    }
}

 

그런데 강사님이 말씀해주신 completing은 마치 특정 코루틴의 작업이 완료되어도, 다른 코루틴의 작업이 실패했을 때 다시 취소처리하기 위한(그래서 Structured Concurrency를 달성하기 위한) 수단인것처럼 말씀해주셨는데, 실제로 어떤식으로 동작하는지를 잘 이해가 안갑니다

 

예를 들어 제가 처음 강의를 들었을 때는, 아래의 코드에서 우선적으로 첫번재 launch 실행 -> completing상태 -> 두번째 launch 실행 -> 예외발생 -> 첫번재 코루틴이 다시 cancelling이 되어야 한다고 이해했는데..

그러면 아래 코드에서 첫번째 코루틴에서 cancellationException이 잡혀서 "First Child Coroutine caught an exception: ${e.message}" 가 출력되어야 할 것 같은데 그러지 않더라구요.

 

아마 첫번째 코루틴이 completing이 아닌 completed상태가 되어서 더이상 영향을 받지 않게 되는 것 같은데.. completing이 정확히 어떤 상태인지가 궁금합니다

fun main(): Unit = runBlocking {
    launch {
        try {
                delay(500L)
                println("First Child Coroutine Completed Successfully")
            } catch (e: Exception) {
                println("First Child Coroutine caught an exception: ${e.message}")
            }
    }

    launch {
        delay(700L)
        throw IllegalArgumentException("Second Child Corutine Exception~~~!")
    }
}
// 출력결과
First Child Coroutine Completed Successfully
Exception in thread "main" java.lang.IllegalArgumentException: Second Child Corutine Exception~~~!
...

 

 

 

답변 1

0

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요! xeroman님! 🙂 항상 좋은 질문 남겨주셔서 감사드립니다.

 

결론적으로 말씀드리면, Completing 상태는 다른 child를 기다리고 있는 상태가 맞습니다 🙂

보다 정확한 이해를 위해서는 Job.kt 공식 설명을 보시는게 빠를텐데요!

https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/

 

여기 문서를 보시면 각 상태 별로 isXXX 속성이 모두 다른 것을 확인할 수 있습니다. 예를 들어 Completing 은 아직 코루틴이 활성화 되어 있으나 완료되지는 않았고, 취소되지도 않은 상태라고 생각할 수 있죠!

image.png

 

아래 다이어 그램을 보시면 조금 더 명확하게 이해하실 수 있습니다. completing은 "Wait Children"이라고 되어 있는데요! 만약 내가 자식 코루틴을 갖고 있는데 아직 그 자식 코루틴이 하나라도 끝나지 않았다면 기다린다는 뜻이죠.

image.png

보내주신 예시에서는 First Coroutine이 자식 코루틴도 존재하지 않고, 본인의 delay 기간도 모두 끝났기 때문에 Completed 상태에 접어들어 예외가 발생하지 않았고요!

만약

runBlokcing (코루틴 1번)

  • launch (코루틴 2번)

    • async (코루틴 4번)

  • launch (코루틴 3번)

처럼 launch 아래에 또 다른 코루틴이 있다면 completing 상태이기 때문에 의도하신 First Child Coroutine caught an exception 출력을 확인하실 수 있을 겁니다 🙂

 

아마 강의에서도 "부모 코루틴 입장에서 자식 코루틴이 있으면" competing이라고 말씀드렸을 거에요. runBlokcing 가 부모, launch 가 자식인 상황에서, 자식인 launch 가 실패하면 competing 상태였던 부모 runBlocking 도 실패해야 하는거죠.

또한 이제 실패하게 된 runBlocking 아래에 아직 종료되지 않은 또 다른 자식이 있다면 그 자식들도 모두 취소 시키게 되고요! (structured concurrency 입니다!)

image.png

혹시나 강의에서 애매하게 설명한 부분이 있는 것 같으시면 편하게 짚어주세요! 저도 함께 확인해보돌고 하겠습니다. 답변이 도움이 되었으면 좋겠습니다. 감사합니다! 🙂 🙇

xeroman님의 프로필 이미지
xeroman
질문자

아.. 제가 놓쳣나 봅니다.. 자식이 있을때만 completing 상태가 되어서 기다리는거군요.. 감사합니다!

xeroman님의 프로필 이미지
xeroman

작성한 질문수

질문하기