Job이 부모-자식 관계를 구성하는 방법
- 코루틴이 시작될 때 부모 Job이 전달되면, 부모 Job은 자식 Job을 등록
- 자식 Job은 자신의 parentHandle에 부모와 연결된 핸들을 저장
- 부모 Job은 자식 Job을 리스트 형태로 관리하고, 자식이 실패하거나 취소되면 이를 감지해 반응할 수 있음
1. initParentJob(parent: Job?)
protected fun initParentJob(parent: Job?) {
assert { parentHandle == null }
if (parent == null) {
parentHandle = NonDisposableHandle
return
}
parent.start() // 자식에서 parent.start()는 왜 해주는 것?
val handle = parent.attachChild(this)
parentHandle = handle
if (isCompleted) {
handle.dispose()
parentHandle = NonDisposableHandle
}
}
- 자식 Job이 생성될 때 부모 Job이 있다면 attachChild()를 호출하여 부모를 연결
- 완료된 Job이라면 핸들을 즉시 정리함
2. attachChild(child: ChildJob): ChildHandle
public final override fun attachChild(child: ChildJob): ChildHandle {
val node = ChildHandleNode(child).also { it.job = this }
val added = tryPutNodeIntoList(node) { _, list ->
// 핸들러 리스트에 자식 노드를 추가
val addedBeforeCancellation = list.addLast(
node,
LIST_ON_COMPLETION_PERMISSION or LIST_CHILD_PERMISSION or LIST_CANCELLATION_PERMISSION
)
if (addedBeforeCancellation) {
true
} else {
// 이미 취소되었거나 완료되었을 때 처리
...
val rootCause = when (val latestState = this.state) {
is Finishing -> latestState.rootCause
else -> (latestState as? CompletedExceptionally)?.cause
}
node.invoke(rootCause) // 자식에게 취소 신호 전달
...
}
}
...
return if (added) node else NonDisposableHandle
}
- 자식 Job은 ChildHandleNode 형태로 부모 Job의 내부 리스트에 추가됨
- 부모가 이미 취소 중이라면 자식은 즉시 취소됨
3. 자식이 취소될 때 : childCancelled(cause: Throwable): Boolean
public open fun childCancelled(cause: Throwable): Boolean {
if (cause is CancellationException) return true
return cancelImpl(cause) && handlesException
}
- 자식이 CancellationException으로 취소되면 부모는 무시
- '예외가 CancellationException의 서브클래스라면 현재 코루틴을 취소시킬 뿐, 부모로 전파되지 않음
(자식한테는 전파 됨)' - 10장 참고 - 위 코드를 보면 CancellationException인 경우 cancelImpl()을 호출하지 않는 것을 볼 수 있음
- '예외가 CancellationException의 서브클래스라면 현재 코루틴을 취소시킬 뿐, 부모로 전파되지 않음
- 자식이 예외로 실패한 경우, 부모도 실패할지 결정 (handlesException)
추가 포인트
private class SupervisorJobImpl(parent: Job?) : JobImpl(parent) {
override fun childCancelled(cause: Throwable): Boolean = false
}
- SupervisorJob은 childCancelled()를 override하여 무조건 false를 할당하고 있음
- 자식의 실패를 무시
'독서 > 코틀린 코루틴' 카테고리의 다른 글
[ 코틀린 코루틴 - 13장 ] 코루틴 스코프 만들기 (1) | 2025.05.21 |
---|---|
[ 코틀린 코루틴 - 12장] 디스패처 (0) | 2025.05.21 |
[ 코틀린 코루틴 - 11장 ] 코루틴 스코프 함수 (0) | 2025.05.14 |
[ 코틀린 코루틴 - 9장 ] 취소 (1) | 2025.05.08 |
[ 코틀린 코루틴 - 8장 ] 잡 (0) | 2025.05.08 |