what's a good way to do things concurrently in `in...
# coroutines
v
what's a good way to do things concurrently in
init {}
?
d
runBlocking { launch { /* task */} }
?
v
this for some reason got "stuck" when instantiated from within a Dispatchers.Default
g
Not the best pattern to have blocking code in init, better to provide asyncronous builder function for it
☝🏼 3
do you have reproduction sample when it “stuck”?
v
no 😕 I just moved it all to
CompletableFuture
and
.join
and moved on; will try to figure out "where" it got stuck when I get around to it again
g
why do you need CompletableFuture with coroutines? At least for this case
v
I don't; wanted to know if there's a "standard" way to do concurrency in init given my
runBlocking
attempt got "stuck"
g
Those are 2 different problems
“stucked” runBlocking probably means that your code inside has some deadlock, hard to say without sample, but most probably just some bug in your implementations
second problem “how to do something concurrent in init”, you can do that as Dominic suggest, if you want make it blocking, so object cannot be created until operation is finished But imo it’s very bad pattern, object creation shouldn’t block for long time
if create object before operation is finished is fine, just launch a coroutine from init, no need to use runBlocking (I would also probably avoid it, harder to test and adds background tasks, but better then blocking)
if you still want to create object only when all you operations are finished, I would recommend use factory method (even better if it suspend), which does all operations asyncronously in parallel and create object after that and return instance of it It also work well with private constructor and invoke operator in companion object. so it allows you make almost real suspend constructor
o
suspend init { }
g
I don't think that I buy it, opens all kind compatibility issues with Java and all other platforms Also init block is not a part of public API or signature, but adding suspending init means that class constructor also become suspending, so it will break all non-suspend clients
j
I would suggest to create a
suspend
factory method on the companion object that does all the concurrent stuff needed to initialize your object, e.g.:
Copy code
class MyClass(val param1: String, val param2: String) {
  companion object {
    suspend operator fun invoke(): MyClass {
      return coroutineScope { 
        val param1 = async { ... }
        val param2 = async { ... }
        MyClass(param1.await(), param2.await())
      }
    }
  }
}
Oops sorry @gildor, just saw you suggested the same 🙂