https://kotlinlang.org logo
#coroutines
Title
# coroutines
m

Mani

10/20/2019, 9:12 AM
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()
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?
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
4 Views