Folks, I am writing my first coroutine. In the follow piece of code, I am fetching a bunch of objects and then doing a IO call with other service. Need some feedback whether my understanding of coroutine is correct.
Copy code
val allWarehouses: List<Warehouse> = getWarehouses()
GlobalScope.launch(<http://Dispatchers.IO|Dispatchers.IO>) {
allWarehouses.forEach { warehouse ->
val notes = getNotes()
// I want to run this loop in parallel
notes.forEach {
serviceClient.markDone(note) // this is an IO call
}
}
}
I want to run the forEach operation in parallel. Is this the right way of doing?
a
Allan Wang
10/20/2019, 9:26 AM
Everything is within a single launch, so
markDone
will not run in parallel. This job however will be sent to an io thread relative to the contents outside of the launch. If you want to run all
markDone
in parallel, launch a separate task for each one.
m
Mani
10/20/2019, 9:27 AM
separate task as in, put this another
launch {}
?
a
Allan Wang
10/20/2019, 9:41 AM
Yes. You should essentially have your launch inside the for loop
g
gildor
10/20/2019, 9:44 AM
Wrap every operation to
async { }
using map:
notes.map { async { markDone() } }.awaitAll()
gildor
10/20/2019, 9:45 AM
But you should understand that markDone must be non-blocking, so it's not how parallel stream works, which created to parallel blocking operation using forkJoin
m
Mani
10/20/2019, 9:57 AM
thank you both 🙂 So, is the outer
launch(<http://Dispatchers.IO|Dispatchers.IO>)
in the right place?
Mani
10/20/2019, 10:35 AM
Also, if one of the
markDone
request fails, what will happen to others?
g
gildor
10/20/2019, 11:16 AM
It will throw exception when it fail and cancel other requests, but you can handle it, by replacing awaitAll() with map ++ await() and try/catch