https://kotlinlang.org logo
Docs
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
coroutines
  • r

    rocketraman

    11/17/2018, 4:03 PM
    I've got a JVM process using coroutines 1.0.0 that has a thread like this that appears to be in a tight loop and using 100% CPU:
    "DefaultDispatcher-worker-5" - Thread t@95
       java.lang.Thread.State: RUNNABLE
    	at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
    	at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
    	at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
    	at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
    	- locked <1c724d56> (a sun.nio.ch.Util$3)
    	- locked <2daa5d57> (a java.util.Collections$UnmodifiableSet)
    	- locked <69cba374> (a sun.nio.ch.EPollSelectorImpl)
    	at sun.nio.ch.SelectorImpl.selectNow(SelectorImpl.java:105)
    	at io.ktor.network.selector.ActorSelectorManager.process(ActorSelectorManager.kt:76)
    	at io.ktor.network.selector.ActorSelectorManager$process$1.invokeSuspend(ActorSelectorManager.kt)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
    	at kotlinx.coroutines.DispatchedTask$DefaultImpls.run(Dispatched.kt:235)
    	at kotlinx.coroutines.DispatchedContinuation.run(Dispatched.kt:81)
    	at kotlinx.coroutines.scheduling.Task.run(Tasks.kt:94)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:586)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:732)
    
       Locked ownable synchronizers:
    	- None
    
    "DefaultDispatcher-worker-5" - Thread t@78
       java.lang.Thread.State: TIMED_WAITING
    	at sun.misc.Unsafe.park(Native Method)
    	at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:338)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.doPark(CoroutineScheduler.kt:835)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.cpuWorkerIdle(CoroutineScheduler.kt:813)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:721)
    
       Locked ownable synchronizers:
    	- None
    It isn't executing any application code, just continuously parking/unparking, AFAICT. How can I tell what is going on here and why this has happened?
    l
    v
    • 3
    • 7
  • m

    MrNiamh

    11/17/2018, 4:13 PM
    I have some simple code like the above, im trying to migrate to 1.3 now though and can't see what I would migrate Job to? I am quite new to coroutines so excuse me if it's a silly question
    g
    • 2
    • 3
  • i

    igor.wojda

    11/18/2018, 2:58 PM
    I need some introduction into more advanced parts of coroutines. Just for simplicity let’s assume that we have 3 views that are retrieving the same data from repository (so 3 views are calling the same repository method at the same time). This repository method under the hood makes a network call, so we don’t want to make multiple requestes:
    View1 calls repos.getData() - start downloading data
    View2 calls repos.getData() - data download in progress so just wait for result
    View2 calls repos.getData() - data download in progress so just wait for result
    How this can be achieved?
    t
    r
    g
    • 4
    • 6
  • m

    Massimo Carli

    11/18/2018, 11:29 PM
    Question about coroutines. Why this code doesn't work in case of a channel that is closed at the sender side? If I add the commented delay() the
    isClosedForReceive
    has more chances to be updated and stop the cycle, otherwise, it won't and I get an exception. Basically, there's a race condition on the
    isClosedForReceive
    property that doesn't allow me to use it as a condition for stop receiving.
    while (!kotlinChannel.isClosedForReceive) {
          val data = kotlinChannel.receive()
          delay(1) // NEEDED IN ORDER TO UPDATE (most of the time) isClosedForReceive
          println(data)
        }
    a
    p
    o
    • 4
    • 15
  • i

    Icaro Temponi

    11/19/2018, 7:43 PM
    Thank you @jw, with your extension plus this one:
    suspend fun suspendCoroutineWithoutReturn(fn: (Continuation<Unit>) -> Unit) = suspendCoroutine(fn)
    I was able to get exactly what i wanted:
    suspend fun <T : AppCompatActivity> T.awaitRunOnUi(fn: T.() -> Unit) {
        suspendCoroutineWithoutReturn { continuation ->
            runOnUiThread {
                fn()
                continuation.resume()
            }
        }
    }
    l
    • 2
    • 8
  • o

    Olekss

    11/20/2018, 10:53 AM
    Do I understand correctly that if I have coroutine, and other sub-coroutines inside it, and I "cancel" (exit) it, the gargbage collector does cleaning up all the sub-co-routines (sorry for confusing terminology)
    g
    • 2
    • 1
  • r

    rocketraman

    11/20/2018, 2:03 PM
    With kotlinx-coroutines-io-jvm 0.1.0-beta1 I used to have code that did
    ByteReadChannel.lookAheadSuspend
    in which I was able to call
    consumeEachRemaining
    , like this:
    fun CoroutineScope.flowableOf(byteReadChannel: ByteReadChannel): Flowable<ByteBuffer> = rxFlowable {
      byteReadChannel.lookAheadSuspend {
        consumeEachRemaining {
          send(it.copy())
          true
        }
      }
    }
    In kotlinx-coroutines-io 0.1.0, this same code compiles but does not work -- it does not read the entire channel. Neither does the corresponding non-suspending
    lookAhead
    method work.
    o
    c
    • 3
    • 53
  • b

    bdawg.io

    11/20/2018, 9:46 PM
    For example
    val rootJob = Job()
    val rootContext = Dispatchers.Default + rootJob
    
    val otherJob = Job()
    val otherScope = object : CoroutineScope {
        override val coroutineContext = rootContext + otherJob
    }
    otherScope.doSomethingAsync()
    otherScope.doSomethingElseAsync()
    
    rootJob.cancel() // will this cancel items from otherJob?
    d
    g
    • 3
    • 3
  • b

    bdawg.io

    11/20/2018, 11:02 PM
    Is there a version of
    Job
    that can be created similar to
    fun Job(parent: Job? = null)
    where
    cancelsParent = false
    a
    • 2
    • 1
  • j

    Joris PZ

    11/21/2018, 7:11 AM
    Suppose I have this structure:
    suspend fun functionA() {
        // A1
        functionB()
        // A2
    }
    
    suspend fun functionB() {
        // B1
        delay(1000)
        // B2
    }
    where
    A1
    ,
    A2
    etc denote normal, non-suspending code blocks. I'm trying to understand how these code blocks are scheduled on the available threads. Suppose
    functionA
    is currently executing on some thread
    T1
    , using a dispatcher that has multiple threads available. The call to
    functionB
    is a suspension point - is it correct to say that at that point, executing of my code may be suspended to allow some other work to be done on
    T1
    ? In that case, does that also mean that
    B1
    can be scheduled on a different thread? I'm pretty sure this happens around the call to
    delay
    , but I'm uncertain about my own code. Similarly, what about
    B2
    and
    A2
    ? Are they guaranteed to be executed on the same thread, or is exiting a suspending function also a suspend point?
    🇳🇴 1
    e
    • 2
    • 2
  • g

    goldin

    11/21/2018, 8:07 AM
    Hi. In the early versions of Coroutines, there were the usual Coroutines Builders, but now in version 1.0.1, methods: launch, asynch extensions of CoroutineScope. Are there any explanations or examples of which CoroutineScope should be used?
    g
    • 2
    • 3
  • e

    Elisabet Svensson Duranovic

    11/21/2018, 12:22 PM
    Hello! We have just upgraded kotlin and coroutines for our service. One thing noted was that main can now be a suspend method. What happens if main gets suspended? Is there any considerations when having long-lived applications? (previously we did a runBlocking { application.start() }, now we just do application.start())
    m
    • 2
    • 12
  • j

    Jonathan

    11/21/2018, 1:38 PM
    Why isn't this enough for IntelliJ to stop warning about experimental usages of kotlinx.coroutines?
    -.xml
    h
    • 2
    • 5
  • s

    Saša Šijak

    11/21/2018, 3:33 PM
    is Dispatchers.IO correct coroutine context to execute sql db queries in ktor app?
    j
    • 2
    • 1
  • a

    Albert

    11/21/2018, 7:44 PM
    Is there an easy way to get everything what is currently in a channel? For example if I do something like
    channel.take(10)
    and there are currently only 8 elements, I want to have those 8 elements instead of waiting until it hits 10
    d
    • 2
    • 2
  • j

    jw

    11/22/2018, 2:36 AM
    It's doing other enqueued work
    r
    e
    l
    • 4
    • 7
  • a

    asad.awadia

    11/22/2018, 2:48 AM
    Still trying to wrap my head around how suspending functions and coroutines come into play in a full complete production grade app (non android)
    g
    d
    +3
    • 6
    • 31
  • a

    asad.awadia

    11/22/2018, 2:54 AM
    Something that does more than just call delays would be nice lol
    g
    • 2
    • 1
  • j

    julioyg

    11/22/2018, 3:20 PM
    Hi, for testing is there anyway to make my unit tests work if I use
    Dispatchers.Main
    dispatcher, or do I need to mock that guy? I'm getting
    java.lang.IllegalStateException: Module with the Main dispatcher had failed to initialize
    l
    • 2
    • 8
  • l

    louiscad

    11/22/2018, 3:26 PM
    Hi, am I right that any failing
    async
    (and
    launch
    ) block in an
    actor
    will close the
    actor
    and make it stop accepting anything?
    o
    • 2
    • 7
  • d

    dave08

    11/22/2018, 8:06 PM
    Wouldn't it be enough to add a new Job to the async context @louiscad?
    l
    • 2
    • 1
  • d

    dave08

    11/22/2018, 8:32 PM
    Is it better to be using a coroutineScope when all there is is one operation there? To be truthful, I made my own
    launchInScope
    function to do the same thing... just wondering if that's really the intention. If so, why not just abstract away the whole Job concept and let the end user deal only with scopes?
    l
    • 2
    • 34
  • j

    Jonathan

    11/23/2018, 10:13 AM
    Hi guys, can someone please tell me how to disable warnings in IntelliJ for
    ExperimentalCoroutinesApi
    when using maven? (the following is obviously not working)
    <configuration>
    	<args>
    		<args>-Xuse-experimental=kotlin.Experimental</args>
    		<args>-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi</args>
    		<args>-Xuse-experimental=kotlinx.coroutines.ObsoleteCoroutinesApi</args>
    	</args>
    </configuration>
    g
    • 2
    • 12
  • l

    leosan

    11/23/2018, 12:46 PM
    which is the best approach for an offline first approach?
    Case: I have to fetch from api (if fails)> from cache (if fails) -> catrastrophic failure handling
    So first case would be something like Using lambdas
    fun getContent(){
    		launch{
    		    try{
    		    val content =useCase.getContent(errorLambdaCallback= {handleError(it)})
    			showContent(content)
    			} catch(e:Exception){
    			  handleError(e)
    			}
    		}
    	}
    Or use channels to communicate back that some error happened but the cache is retrieved? or there is actually a better way to handle this case where I need to handle error and get the content
    h
    • 2
    • 12
  • u

    uhe

    11/23/2018, 2:25 PM
    In this snippet, the theoretical resource is not released, when the coroutineContext is cancelled before
    produce
    has been started. Is it possible to avoid this race?
    -.kt
    s
    • 2
    • 3
  • m

    myanmarking

    11/23/2018, 3:28 PM
    the only way to prevent a crash is add a try block inside
    someFunctionThatCrash
    Can any1 explain this behavior to me please?
    a
    • 2
    • 2
  • z

    zak.taccardi

    11/23/2018, 7:01 PM
    FYI this is a good reason not to use exceptions as a way to control flow. Use sealed classes
    l
    a
    • 3
    • 11
  • t

    Tolriq

    11/23/2018, 8:41 PM
    If your function is marked suspend then you are calling it from a coroutineScope already. So it's maybe better to do
    suspend fun fetchCharacterData(): CharacterGenerator.CharacterData = {
                val apiData = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { URL(CHARACTER_DATA_ENDPOINT).readText()} 
                CharacterGenerator.fromApiData(apiData)
            }
    to start on good bases.
    z
    m
    • 3
    • 6
  • t

    Tolriq

    11/24/2018, 10:16 AM
    So finally went to prod with coroutines 🙂 I'm just facing a rare crash for the moment on a specific device (Galaxy Tab Android 5.0.2) have anyone saw this one before?
    -.txt
    l
    • 2
    • 7
  • s

    Sam

    11/24/2018, 5:04 PM
    Does runBlocking's block thread on suspend also apply to child coroutines?
    d
    b
    +2
    • 5
    • 45
Powered by Linen
Title
s

Sam

11/24/2018, 5:04 PM
Does runBlocking's block thread on suspend also apply to child coroutines?
d

Dominaezzz

11/24/2018, 5:16 PM
You want
runBlocking
to block the calling thread until all the `launch`ed child coroutines finish?
s

Sam

11/24/2018, 5:44 PM
It already does that. My question is to guarantee the sequence of child
runBlocking {
        launch {
            delay( 200 )
            println( "first launch done" )
        }

        launch {
            delay( 100 )
            println( "second launch done" )
        }
    }
d

Dominaezzz

11/24/2018, 5:45 PM
Oh, you want to the first
launch
to finish before the second
launch
?
s

Sam

11/24/2018, 5:45 PM
yes
execute all in a sequence blocking on suspend calls (irrespective of whether they are from same coroutine or child or further nested levels)
b

bdawg.io

11/24/2018, 5:47 PM
You would need to have the second one wait
d

Dominaezzz

11/24/2018, 5:47 PM
Then why are you `launch`ing them? `launch`ing means concurrency.
s

Sam

11/24/2018, 5:48 PM
yes in actual code but lets say in a testing code
b

bdawg.io

11/24/2018, 5:48 PM
In which case, as @Dominaezzz just said, is not concurrency so
launch
is just overhead at this point
s

Sam

11/24/2018, 5:50 PM
or let me rephrase it
repeat( 1000 ) {

        runBlocking {
            launch {
                println( "first launch done" )
            }

            launch {
                println( "second launch done" )
            }
        }

    }
the above launch doesn't have any delay and calling it under runBlocking 1000 or any number of times completes the first launch before the second one
Is that just a coincidence or working as design?
d

Dominaezzz

11/24/2018, 5:51 PM
Coincidence.
It's just very very unlikely for the second launch to finish first in this case.
But there's no documentation officially describing coroutine launch/finish order.
👍 1
s

Sam

11/24/2018, 5:54 PM
I thought so too but then i tried replacing runBlocking with a GlobalScope.launch and a sleep, i see the race
repeat( 10 ) {

        GlobalScope.launch {
            launch {
                println( "first launch done" )
            }

            launch {
                println( "second launch done" )
            }
        }

        Thread.sleep (100 )

    }
this time i see the race when i repeat it just 10 times
but i don't see that with runBlocking, thats why i was curious
After looking at this, i'm questioning the coincidence of runBlocking
runBlocking {

        launch {
            var sum  = 0

            repeat( 100_000_0000 ) {
                sum += 1
            }

            println( "first launch sum $sum" )
        }

        launch {
            var sum = 0

            repeat( 10 ) {
                sum += 1
            }

            println( "second launch sum $sum" )
        }
    }
first launch sum 1000000000 second launch sum 10
d

Dominaezzz

11/24/2018, 6:44 PM
Curious.
s

Sam

11/24/2018, 6:49 PM
Yeah, runBlocking for sure seems to influence the order
runBlocking {

        launch {

            val time = measureTimeMillis {

                BigInteger(3500, Random()).nextProbablePrime()

            }

            println( "first launch sum $time" )
        }

        launch {

            println( "second launch sum" )
        }
    }
first launch sum 9087 second launch sum
this is where i got into a rabbit hole when i replaced the lengthy operation in first launch with a suspend call to delay(). In that case, second launch (with no or less delay) completes before the first one
b

bdawg.io

11/24/2018, 7:20 PM
The problem seems to be trying to predict how a concurrency library manages tasks in parallel. runBlocking depends on it's backing dispatcher/event loop. Do you get the same results by using
runBlocking(Dispatchers.Default) { ... }
?
👍 1
s

Sam

11/24/2018, 7:23 PM
With Dispatchers.Default, i get expected results
the task with less activity ( with or without usage of delay in both task) completes first
b

bdawg.io

11/24/2018, 7:24 PM
Using
GlobalScope.launch
will give you a different result because it uses Dispatchers.Default/CommonPool to obtain additional threads which allows more of your concurrent jobs to execute in parallel.
s

Sam

11/24/2018, 7:25 PM
Gotcha
b

bdawg.io

11/24/2018, 7:28 PM
So if you use
runBlocking
by itself, it only has the current thread, so your first launch goes first on that single thread until it completes or suspends (which is why your 1 billion sum completes before the second starts), there's no additional threads for the second job to go in parallel
s

Sam

11/24/2018, 7:30 PM
and delay suspends the first launch, causing the second one to execute
Thanks, with that it makes sense
So in other words, runBlocking when used by itself guarantees sequential order of child coroutines as long as none of them invoke any suspend functions
b

bdawg.io

11/24/2018, 7:37 PM
There's no documented guarantee or contract that will be the case, but base on observation of the current implementation that does occur 👍
s

Sam

11/24/2018, 7:38 PM
Got it
https://github.com/Kotlin/kotlinx.coroutines/blob/master/docs/basics.md#scope-builder does have the complex nested case
Yeah, the nitty gritty is not at all obvious for newcomers
d

Daniel Tam

11/25/2018, 10:16 AM
if you want the first launch to finish first every time then you can wrap it in a coroutineScope
or just
join
on it
p

pankajrai

11/25/2018, 12:15 PM
launch and async are coroutine builder where these coroutines run in parallel. In case you want to run them in sequence than use await method of async and pass LAZY as a constructor parameter to async coroutine builder
Do not use GlobalScope its like building a demon thread for better structured concurrency use some kind of scope like runBlocking is one such which limits the scope to a function call.
runBlocking will block the thread until all it's child execution is done so it's not so good to use runBlocking while building Android apps
b

bdawg.io

11/25/2018, 10:25 PM
I think the point of the OP was to understand the dispatching behavior while inside of a scope launched via
runBlocking
View count: 3