0
votes

I'm new to coroutines and trying to leverage them to call a time consuming method a couple of times in less time

fun callAPI(idList: Collection<String>): List<String> {
       
        val storedIds = mutableListOf<String>()
        runBlocking {
             val ids = idList.map { data ->
                   async {timeConsumingMethod(data)}
                    }.map { it.await() }
                    storedIds.addAll(ids)

        }
        return storedIds
    }

I need all the calls to timeConsumingMethod to run in parallel, but i don't want callAPI to return until after all the timeConsumingMethods finish.

Running this i see the timeConsumingMethods are running synchronously

Can anyone give me a hand in understanding what mistake i'm missing?

1
How are you determining that the methods are running synchronously? - Louis Wasserman
there is logging in the timeConsumingMethod that shows the rest call it makes finishes before the next one kicks off - Adam Golden
use async(Dispatchers.IO) { ... } - IR42
Yea, cuz runBlocking is single threaded they'll run sequencially, why are you using runBlocking though? Any problem making the function suspend? And same suggestion as given by IR42, for a blocking process consider using Dispatchers.IO (otherwise Dispatchers.Default for CPU driven tasks). - Animesh Sahu
callAPI is called from a non-suspended method. I actually did end up using Dispatchers.Default, which worked so if @IR42 wants to make a response i'll make that the selected answer. - Adam Golden

1 Answers

0
votes

You need to specify a dispatcher other than runBlocking's default single thread dispatcher, or nothing can run in parallel.

Your code can also be rearranged a bit for clarity/conciseness.

fun callAPI(idList: Collection<String>): List<String> = runBlocking(Dispatchers.IO) {
    idList.map {
        async { timeConsumingMethod(it) }
    }.awaitAll()
}

If you are working with a UI that you don't want to freeze during the operation, you should consider making this a suspend function and responding to the results when they are ready, rather than using runBlocking.