<@U6P03BM0W> The rule of thumb for coroutines is s...
# coroutines
e
@dave08 The rule of thumb for coroutines is simple. If you have to ensure that certain code runs in a certain context (because it touches some confined shared mutable state like UI classes or because it is blocking), then you specify the context explicitly for this code. If your code is pure and does not care about its execution context (which should be true for most of the well-designed code) , then you leave the context specification out and go with default.
d
What about
runBlocking
or
launch(Unconfined)
, is there a difference?
Thanks, with all this I'm starting to get the big picture of how to write things, but these specific points I mentioned are still a bit fuzzy... also with
yield
?
e
runBlocking
confines the code to the invoker thread and blocks the invoker thread, while
launch(Unconfined)
does not confine the code to any thread and does not block the invoker thread (invoker thread is busy only until coroutine suspends). Big difference. I’d suggest to (re)read the guide. This example from the guide explicitly shows this difference between thread-confined and unconfined, for example: https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md#unconfined-vs-confined-dispatcher
d
I read and reread the guide tons of times, but what you just said now makes it clearer. I wanted to know if even though the Uncfined coroutine is running in other threads, maybe the main thread is still waiting for the result... I just wondered why in the reactive guide it was stated that
Unconfined
is like no schedulers.. which in rx if we do a flatMap with a nested observable that uses a scheduler, the main observable (with no scheduler) that recieves the result will still be waiting on the thread it was run... whereas Unconfined might not do that if it ends up on another thread. So in conclusion, no schedulers in rx != Unconfined but rather to runBlocking surrounding it... or maybe only similar in some aspects...
e
Not really. No schedulers in Rx would not block your invoker thread for the duration of operation. Try to observe Rx
interval
operator without explicit scheduler. Will the invoker get blocked?
The answer is No. If you don’t specify scheduler in Rx, your observer will be unconfined. It will run in whatever thread that happens to be there, depending on the implementation details for the corresponding operator
d
observable.flatMap { Observable.interval(...) }.subscribe()
?
e
Copy code
fun main(args: Array<String>) {
    Observable.interval(1, TimeUnit.SECONDS).subscribe {
        println(Thread.currentThread().name)
    }
    println("Was I blocked or continue to run immediately?")
    Thread.sleep(10_000)
}
d
Right, in your example I agree, but my example, the first observable should be blocking and only receive the result from the interval? It could be you're right that it's Unconfined... if so, I'll have to look over my code again... I have some code out like that that seems to work... 😧. Thanks for all the explanations!
e
That is the big problem of Rx. Everything is unconfined by default, so it is easy to write code that happens to work (by chance of everything happen to be executing in the right thread), but will stop working if you change something (the implementation of your observable, for example).
💯 2