voddan
09/18/2018, 1:58 PMcoroutineScope { } only inside another coroutine or a suspending function? What's wrong with fun main() = coroutineScope { <do the majic> }? Do I need runBlocking{} there? What's the meaning of runBlocking with scoped coroutines if scopes wait for their children?Vsevolod Tolstopyatov [JB]
09/18/2018, 2:06 PMvoddan
09/18/2018, 2:11 PMvoddan
09/18/2018, 2:11 PMVsevolod Tolstopyatov [JB]
09/18/2018, 2:15 PMthose sections do not explain the “why”, do they?
The main difference between runBlocking and coroutineScope is that the latter does not block the current thread while waiting for all children to complete.You can think of
coroutineScope as about syntactic sugar for
val job = launch(coroutineContext, parent = Job()) {
// Here is the body of currentScope
}
job.join()
job.throwExceptionIfPresent()Vsevolod Tolstopyatov [JB]
09/18/2018, 2:16 PMcoroutineScope is more or less suspending version of runBlocking, which provides dispatcher from current coroutineContext for all childrenvoddan
09/18/2018, 2:18 PMIn other words,is more or less suspending version ofcoroutineScope,runBlocking
runBlocking is like coroutineScoped with pre-selected dispatcher that always blocks, correct?Vsevolod Tolstopyatov [JB]
09/18/2018, 2:21 PMrunBlocking blocks until given coroutine completes
coroutineScope suspends until given coroutine and all children of the scope complete, no matter in what dispatcherVsevolod Tolstopyatov [JB]
09/18/2018, 2:23 PMvoddan
09/18/2018, 2:24 PMvoddan
09/18/2018, 2:25 PMrunBlocking into coroutineScope (without a receiver)voddan
09/18/2018, 2:26 PMVsevolod Tolstopyatov [JB]
09/18/2018, 2:39 PMcoroutineScope will not compile because of resolution ambiguity
2) We prefer to explicitly reflect the fact that builder blocks a thread
3) After this change it will be possible to accidentally misuse suspending and blocking fun
4) runBlocking still should provide a scope otherwise everyone will be forced to use GlobalScope where it’s not really necessaryvoddan
09/18/2018, 2:57 PM2) We prefer to explicitly reflect the fact that builder blocks a threadAny coroutine scope stops execution flow. How it maps to threads is an implementation detail desided by the dispatcher.
3) After this change it will be possible to accidentally misuse suspending and blocking funHow so? If I create a coroutine scope, it will wait for its children.
4)Not sure I follow here. GlobalScope should almost never be used. I don't see how unification of scope builders will change thatstill should provide a scope otherwise everyone will be forced to userunBlockingwhere it’s not really necessaryGlobalScope
voddan
09/18/2018, 3:00 PMVsevolod Tolstopyatov [JB]
09/18/2018, 3:06 PMVsevolod Tolstopyatov [JB]
09/18/2018, 3:11 PMHow it maps to threads is an implementation detailIt’s not and it has nothing to do with dispatcher. Blocking and suspension are not synonyms. E.g. in
blockingFoo: String and asyncFoo: Future<String> whether function is async or not is not an implementation detail. Same for blocking vs. suspending, the only difference is that compiler hides a complexity behind callbacks.
How so?Because they have the same name 🙂
Not sure I follow hereIf
runBlocking lambda won’t have a receiver, then it would be impossible to write
runBlocking { launch { ... } } because now scope is missing.Dico
09/18/2018, 4:42 PMvoddan
09/18/2018, 7:52 PM