Where is task to process big list of items in sequential-parallel way: split big list to chunks, process chunks one after another, process items from each chunk in parallel. Implementing this task, I encounter a problem and reduce that task to reproduce it in simplest way.
val rootScope = CoroutineScope(Dispatchers.IO)
val list: List<Int> = listOf(1,2,3,4,5)
rootScope.launch {
val rootLocalScope = this
log("-----> rootScope (start)")
launch {
val mediumLocalScope = this
list.map { i ->
//
// Replace rootLocalScope to mediumLocalScope in SupervisorJob() and hangs up work...
//
launch (SupervisorJob(rootLocalScope.coroutineContext.job)) {
log("Downloading file-$i")
delay(1000)
}
}.joinAll()
}.join()
log("-----> rootScope (finish)")
}
Remark: all .join() are required, there is no right sequence of work without it.
Output is:
With SupervisorJob(rootLocalScope.coroutineContext.job):
========= work() ========
-----> rootScope (start)
Downloading file-1
Downloading file-2
Downloading file-3
Downloading file-4
Downloading file-5
-----> rootScope (finish)
With SupervisorJob(mediumLocalScope.coroutineContext.job):
========= work() ========
-----> rootScope (start)
Downloading file-1
Downloading file-2
Downloading file-3
Downloading file-4
Downloading file-5
*I.e. top level coroutine not reached its finish...*
So, the question: why SupervisorJob(mediumLocalScope.coroutineContext.job) not works?
I found on StackOverflow similar theme. Shortly: you shoud manually call .complete() on intermediate job (SupervisorJob in discussed case, but simple Job behaves the same) after .joinAll() child jobs.