If I have, lets say 3 functions that write to a da...
# coroutines
d
If I have, lets say 3 functions that write to a database. They are independent of each other (in that the writes of one function does not affect the writes of another function into the db) and I want to run each in their own coroutine, not caring about any return code or status.
m
Well, the first example will run all writes in parallel while the second one will run the one after the other. So it just depends on what you want to do.
d
parallelism 🙂
what happens if I change the function signature to this?
m
Then you have to do the first one. The second one doesn’t run them in parallel.
d
suspend fun writeIntoTable1() = GlobalScope.launch {...}
2
I suppose then, each function would then run in parallel
m
Yes, but that is not idiomatic. A suspend function is expected to complete all work before it returns. Also, you shouldn’t use
GlobalScope
. Your coroutines could leak.
d
I see I see
so the first approach would be better?
m
I think I would do this:
Copy code
fun CoroutineScope.doSomething() {
    launch(<http://Dispatchers.IO|Dispatchers.IO>) {
        writeIntoTable1()
    }

    launch(<http://Dispatchers.IO|Dispatchers.IO>) {
        writeIntoTable2()
    }

    launch(<http://Dispatchers.IO|Dispatchers.IO>) {
        writeIntoTable3()
    }
}
d
great, how then is the doSoemthing invoked (to kick everything off?)
m
Let the caller decide the scope. Taking the
CoroutineScope
as the receiver parameter is a convention.
u
But you can drop the
suspend
keyword bacause you are not suspending, but returning imediately:
fun CoroutineScope.writeIntoTable1Async() = launch {...}
d
k
m
Call it like
myScope.doSomething()
.
Yeah, that’s also a possibility @uli👍
d
ta! food for thought
🙂
works great, thank you both! 🙂
u
how did you do it now?
For example try to handle exception in this case. Or even worse if you want to cancel other operations if one of them failed And copy dispatcher is also suboptimal. Most probably it should look like:
Copy code
suspend fun doSomething() { 
coroutineScope { // or withContext(IO) if you really need IO disaptcher
    launch {
        writeIntoTable1()
    }
    launch {
        writeIntoTable2()
    }
    launch {
        writeIntoTable3()
    }    
}
}
And on call site:
Copy code
myLocalScope.launch { doSomething }
or any other semantics that suits better call site (use await, just call suspend function etc)
d
That's pretty much what I've distilled from the great advice here 🙂
Thank you 🙂