The following code ...
@Test
fun nested_coroutines5() {
log.info("start")
val res = runBlocking {
launch {
launch {
completeAfter(2500)
}
completeAfter(2000)
}
GlobalScope.launch {
completeAfter(3000)
}
val d1 = async {
completeAfter(500)
1
}
val d2 = async {
completeAfter(1000)
2
}
log.info("before await")
val sum = d1.await() + d2.await()
log.info("after await, before return")
sum
}
log.info("end")
}
produces
5 [main] INFO ScopeTests2 - start
82 [main @coroutine#1] INFO ScopeTests2 - before await
591 [main @coroutine#4] INFO ScopeTests2 - completing
1087 [main @coroutine#5] INFO ScopeTests2 - completing
1088 [main @coroutine#1] INFO ScopeTests2 - after await, before return
2089 [main @coroutine#2] INFO ScopeTests2 - completing
2590 [main @coroutine#6] INFO ScopeTests2 - completing
2591 [main] INFO ScopeTests2 - end
Notice
- The "before await" is reached rather quickly, since launching the inner coroutines doesn't block
- The "after await, before return" is logged at ~1000, after
d1
andd2
complete - However, "end" is only logged at ~2500, after the first child
launch
also completes - That is, the coroutine is only completed when
- Its sequential flow is completed
- Its child coroutines are completed
- Note that the coroutines that takes 3000 ms is not waited for because it isn't a child coroutine.
Tt was created using
GlobalScope
, so it detached from the parent-child tree.
coroutine#1 (completes after max(max(2000ms, 2500ms), 500ms, 1000ms))
coroutine#2 (completes after max(2000ms, 2500ms)
coroutine#6 (completes after 2500ms)
coroutine#3 (not a child from coroutine1)
coroutine#4 (completes after 500ms)
coroutine#5 (completes after 1000ms)