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
  • m

    melatonina

    06/07/2021, 11:17 PM
    Do people feel that
    StateFlow
    is a good replacement for
    LiveData
    on Android? There is often a noticeable delay in updates, which leads to the UI to represent incorrect information when it first shows up. That never happened to me with
    LiveData
    .
    z
    t
    +2
    • 5
    • 21
  • t

    Tim Malseed

    06/08/2021, 3:27 AM
    I keep making this mistake:
    CoroutineScope.launch {
        stateFlowA.collect {
            foo()
        }
        stateFlowB.collect {
            bar()
        }
    }
    And wondering why bar() isn't called. (It's because stateFlowA never completes, as it's a StateFlow). I think I'm just tempted to declare both suspend functions inside the one
    CoroutineScope.launch { }
    block out of convenience. Anyway, the simple solution is to just not make this mistake. But I wonder if I'm doing this because there's a problem with my mental model. I think maybe this comes about because
    launch{}
    is the only operator I ever use to kick-off a suspend fun (I rarely consider
    async
    , and I'm not sure if there are others. I don't have a specific question, just wanted to discuss this and see if anyone else has the same problem. I'm hoping the discussion will help correct my mental model.
    g
    • 2
    • 2
  • s

    Sudhir Singh Khanger

    06/08/2021, 4:37 AM
    Room will use different Dispatchers for transactions and queries. These are derived from the executors you provide when building your Database or by default will use the Architecture Components IO executor. This is the same executor that would be used by LiveData to do background work.
    Does that mean if I use
    withContext(<http://Dispatchers.IO|Dispatchers.IO>) { //db calls }
    then likelihood is that Room merges this with whatever
    Architecture Components IO executor
    it uses internally? Or would
    <http://Dispatchers.IO|Dispatchers.IO>
    overwrite Room's default dispatcher. As far as I understand
    Default
    means
    main
    in Android.
    g
    • 2
    • 5
  • t

    Tim Malseed

    06/08/2021, 4:40 AM
    I've got a couple of 
    StateFlows
     the second depends on the first. But, the second is not emitting when I expect it to..
    m
    • 2
    • 13
  • j

    james

    06/08/2021, 6:31 AM
    I guess more of a design pattern problem. If I have a view model on Android that has 3 flows that it needs to collect from when the view opens, but the flows may need to be restarted based on an event, what is the standard safe way to do this?
    g
    u
    • 3
    • 3
  • h

    Henning B

    06/08/2021, 1:14 PM
    Question about unit tests. I got a repo which I would like to test. It has an ApiService dependency which I mock with mockk. I would like to test, that when I call a suspending function of the repo it calls a certain api function on the correct dispatcher. I know how to verify the api call but have no idea how to make sure the correct dispatcher is used. Is this possible?
    • 1
    • 1
  • c

    christophsturm

    06/08/2021, 1:18 PM
    if i run this code:
    suspend fun main() {
        val executorService = Executors.newWorkStealingPool(1000)
        withContext(executorService.asCoroutineDispatcher()) {
            repeat(1000) {
                async {
                    delay(1000)
                }
            }
        }
        println(executorService)
    }
    at the end the executor service has one task left:
    java.util.concurrent.ForkJoinPool@5079ec1[Running, parallelism = 1000, size = 70, active = 1, running = 1, steals = 2000, tasks = 0, submissions = 0]
    why is that. if i do runBlocking instead of withContext the executor service is empty as expected.
    • 1
    • 1
  • p

    Pablo

    06/08/2021, 1:23 PM
    Does it make sense to have a
    flow
    that inside does an
    async{}
    call? For instance
    flow<List<Foo>>{
      val list = getFromApi()
      val one = async(<http://Dispatchers.IO|Dispatchers.IO>)
      val two = async(<http://Dispatchers.IO|Dispatchers.IO>)
      val correctList = one.await() + two.await()
      emit(correctList)
    }
    Or it's better to use async without flow here? That's pseudo because to do
    async
    I need a
    coroutineScope
    is there any way to get it from the
    flow
    ?
    e
    u
    z
    • 4
    • 4
  • s

    stojan

    06/08/2021, 3:08 PM
    What would be the best way to launch a coroutine in a
    RecyclerView.ViewHolder
    (I need to load an image, and offload that to a background thread) Not sure if this channel, or #android is better....
    a
    • 2
    • 4
  • u

    ursus

    06/09/2021, 4:44 AM
    Is there a flatMap variant which drops upstream emits when body is not completed yet Is overriding concurrency to 1 in flatMapMerge okay or should I have a custom operator
    👀 1
    w
    z
    • 3
    • 6
  • d

    dkim

    06/09/2021, 1:43 PM
    Hi! I've already asked this in #ktor, but seeing how this is related to coroutines, maybe someone could help here? I'm a bit frustrated, so in one part of my program the coroutine that a ktor websocket is running on becomes inactive (before I open the websocket the coroutine is active), so I'm wondering if anyone knows why 🙂 Code where it doesn't work: https://github.com/dkim19375/Tag/blob/master/src/main/kotlin/me/dkim19375/tag/multiplayer/ClientManager.kt#L43-L107 Code where it does work with almost the same code: https://github.com/dkim19375/Tag/blob/master/src/main/kotlin/me/dkim19375/tag/util/Testing.kt Image with the first code snippet hiding the comments is below. Since the coroutine isn't active, the websocket won't work 😞 Ktor: 
    1.6.0
    Kotlin: 
    1.5.10
     (JVM) All dependencies: https://github.com/dkim19375/Tag/blob/master/build.gradle Server log: https://paste.helpch.at/eruzihulol.sql Client log: https://paste.helpch.at/bedemiyihi.sql Note that for both logs I'm using TornadoFX, and in my test class, I'm not using TornadoFX, and this is the log:
    program
    test 1, is active: true
    test 2, is active: true
    Is this an issue towards what I'm doing with ktor or is it something with coroutines? (I'm not sure so I'm asking both channels) EDIT: Figured it out
    d
    • 2
    • 1
  • p

    Paul Woitaschek

    06/10/2021, 8:15 AM
    I find that DelicateCoroutinesApi opt in a little useless. I am purposely using a GlobalScope in one place and what I want to do here is to add a suppress at the place where it's used with a comment. But with the opt in system I need to enable it for the whole module which makes the warning in other places go a away 😕
    g
    • 2
    • 6
  • r

    rtsketo

    06/10/2021, 9:54 AM
    Usually when I want to launch a banch of coroutines but also want to wait for all them to finish, I do something like this:
    val jobs = arrayListOf<Job>()
    aListOfStuff.forEach {
      jobs.add(launch { something(it) })
    }
    
    jobs.joinAll()
    println("All jobs completed!")
    Recently I discovered I can do something similar with
    supervisorScope
    , like so:
    supervisorScope {
      aListOfStuff.forEach {
        launch { something(it) }
      }
    }
    
    println("All jobs completed!")
    Does it completely mimics the behavior I intented the first part to have though? Are there be any mihaps I should be aware of?
    e
    d
    z
    • 4
    • 17
  • s

    Slackbot

    06/10/2021, 11:49 AM
    This message was deleted.
    c
    e
    u
    • 4
    • 21
  • m

    Mark Allanson

    06/10/2021, 3:38 PM
    Would buffered flows be the current best way of fanning out a number of (comparatively) long running http requests and aggregating the results?
    c
    • 2
    • 4
  • k

    kevin.cianfarini

    06/10/2021, 7:43 PM
    It’s failing with this output
    expected: Thread[test,5,main]
    but was : Thread[main @coroutine#1,5,main]
    u
    a
    • 3
    • 17
  • k

    Kirill Vasilenko

    06/11/2021, 8:46 AM
    Hi there! This message is for those who are interested in the opportunity to write their view models in a much simpler way and keep them at the multiplatform level. As you may know,
    StateFlow
    is a really convenient thing for implementing reactive view models, but there is a big problem - when you combine them (with
    combine(...)
    or
    map(...)
    operators) they turn into
    Flow
    that is not so convenient.
    val firstField: StateFlow<String>
    val secondField: StateFlow<Int>
    
    val canDoSomethingScary: Flow<Boolean> = combine(firstField, secondField) { first, second ->
        first.isNotBlank() && second > 0 && second < 10
    }
    
    // method has to be suspended :(
    suspend fun doSomethingScary1() {
        // had to have coroutineScope here :(
        if (!canDoSomethingScary.stateIn(coroutineScope).value) return
        // do something scary
    }
    There is a proposal on GitHub about having an opportunity to combine
    StateFlows
    and get
    StateFlow
    . There are also examples why getting
    Flow
    is not convenient and working code snippets with the solution, using which one will be able to write much clearer code and keep their view models at the multiplatform level right now. Like this
    val firstField: StateFlow<String>
    val secondField: StateFlow<Int>
    
    val canDoSomethingScary: StateFlow<Boolean> = combineStates(firstField, secondField) { first, second ->
        first.isNotBlank() && second > 0 && second < 10
    }
    
    // method doesn't have to be suspended :)
    fun doSomethingScary() {
        if (!canDoSomethingScary.value) return
        // do something scary
    }
    Please vote and discuss the proposal there to induce the Kotlin team to include it (or a better solution) in the
    kotlinx.coroutines
    in the following releases. https://github.com/Kotlin/kotlinx.coroutines/issues/2631
    🙌 1
    e
    a
    +3
    • 6
    • 26
  • m

    Mark Allanson

    06/11/2021, 3:45 PM
    Does it make sense that a
    Deferred
    inside a
    supervisorJob
    continues to report as active until all the co-routines are complete? I was expecting the child jobs move to a completed state once they themselves finished, instead of only transitioning to completed when all have done so.
    b
    • 2
    • 3
  • k

    Karthik Periasami

    06/11/2021, 6:29 PM
    interface RestApi {
        fun get()
        fun post()
        fun put()
        fun delete()
    }
    interface NewRestApi {
        suspend fun get()
        suspend fun post()
        suspend fun put()
        suspend fun delete()
    }
    I am adding a feature in my rest client library to support suspend functions. What is the recommended prefix for suspend method names? I need something to differentiate between the non-suspend functions, to avoid misunderstanding. Any ideas are welcome, I suck at naming.
    f
    w
    +3
    • 6
    • 10
  • s

    Scott Kruse

    06/11/2021, 7:01 PM
    I was reading that
    stateflow
    never completes, so by this reasoning, we should never start collecting on a stateflow from within
    suspend
    function correct?
    e
    • 2
    • 3
  • t

    taponidhi

    06/13/2021, 4:32 AM
    I have some doubts regarding context of coroutines. In @elizarov article Coroutine Context and Scope there is an image showing how context and coroutines creation is handled. What I have understood from it is during launch{} inside a scope, 3 coroutine context are there. One coming from scope(called scope context), another intermediate Parent context(which will be lost since there won’t be any reference to it) and final child context(with a job inside it). Am I correct? I have read coroutines over and over still get confused. If anyone can give me an explanation, it will be huge help. Thanks.
    e
    t
    +2
    • 5
    • 18
  • u

    ursus

    06/13/2021, 9:47 AM
    Is using runBlocking correct way to interface with blocking world when using MutableStateFlow?
    class PermissionManager() {
        private val manualTrigger = MutableSharedFlow<Unit>()
        
        ...
    
        fun notifyPermissionChanged() {
            runBlocking { <---------------------
                manualTrigger.emit(Unit)
            }
        }
    }
    
    class Activity {
    	override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            permissionManager.notifyPermissionChanged()
        }
    }
    tryEmit never does anything
    🇳🇴 1
    b
    j
    +3
    • 6
    • 27
  • v

    Vikas Singh

    06/14/2021, 10:56 AM
    What's difference between CoroutineScope(Dispatchers.IO) + Job() and CoroutineScope(Dispatchers.IO+ Job())
    m
    d
    • 3
    • 5
  • t

    Tiago Nunes

    06/14/2021, 2:12 PM
    Hi everyone, how do I convert a
    List<Flow<T>>
    to a
    Flow<List<T>>
    ? Sounds simple enough but it's bugging my brain 😅
    w
    j
    • 3
    • 5
  • u

    ursus

    06/14/2021, 7:49 PM
    I'm confused on
    trySend
    vs
    trySendBlocking
    in
    callbackFlow
    . I presume it's about backpressure right? If so, to mimic rxjava Observable, I want
    trySendBlocking
    right?
    l
    e
    • 3
    • 8
  • w

    William Reed

    06/14/2021, 8:15 PM
    trying to understand what happens when a coroutine is launched in an IO dispatcher (to help in code review). my co-worker has code that launches in an IO dispatcher with code that has no suspend functions (mostly to conform to a previous interface, but lets hand wave that part). since there are no suspend functions, does calling this method always start a new thread? i’m not familiar with the IO dispatcher internals and even though its well documented code there is a lot of it to look through
    🇳🇴 1
    l
    m
    • 3
    • 3
  • d

    diego-gomez-olvera

    06/15/2021, 9:06 AM
    while investigating coroutines
    Flow
    API a colleague noticed that there are several operators (e.g.
    mapLatest
    ) still experimental. What would be your recommendation about those? Is it safe to adopt them? Is there typically a migration supported in case of deprecation?
    :yes: 1
    z
    • 2
    • 1
  • m

    myanmarking

    06/15/2021, 10:48 AM
    Is it safe to adopt them? Well, the official recommendation would say no. But the unofficial and more reasonable one would say yes, it is safe. The recommended migration will be explained if it comes to that for sure
    :thread-please: 3
    t
    e
    • 3
    • 19
  • o

    Osmium

    06/15/2021, 6:55 PM
    Hi! I'm trying to understand how to use coroutines in a non-coroutines JS frameworks without using GlobalScope a lot. Today I tried to rewrite application using one GlobalScope and nested
    launch
    methods so coroutine hierarchy will be structured. But. How to deal with callbacks?
    fun main() {
        GlobalScope.launch {
            launch {
                root("main") { div("Hello KVision!") }
            }
            launch {
                root("extras") {
                    button {...}.onClick {
                        this@launch.launch {
                            ktorClient.get("/api/users/current") {...} // will not be called
                        }
                    }
                }
            }
        }
    }
    Should I use GlobalScope in case of event listeners like onClick and so on?
    l
    r
    • 3
    • 5
  • t

    Tower Guidev2

    06/16/2021, 8:13 AM
    Hi, I am investigating
    merge(flow1, flow2, flow3...)
    and have the following use case...
    w
    • 2
    • 4
Powered by Linen
Title
t

Tower Guidev2

06/16/2021, 8:13 AM
Hi, I am investigating
merge(flow1, flow2, flow3...)
and have the following use case...
sealed class State {
    object Resting : State()
    object Working : State()
}


fun main() = runBlocking {

    backgroundStartsFirst()

}

@OptIn(ExperimentalCoroutinesApi::class)
suspend fun backgroundStartsFirst() {

    val backgroundFlow = flow {
        emit(State.Resting)
        delay(1000)

        emit(State.Working)
        delay(10000)

        emit(State.Resting)
    }


    val foregroundFlow = flow {
        emit(State.Resting)
        delay(2000)

        emit(State.Working)
        delay(1000)

        emit(State.Resting)
    }

    val workingCount = AtomicInteger(0)

    merge(backgroundFlow, foregroundFlow)
        .collect {

            when (it) {
                State.Working -> {
                    println("SOME ARE WORKING")
                    workingCount.incrementAndGet()
                }
                State.Resting -> {
                    println("SOME ARE RESTING")
                    if (workingCount.get() > 0) workingCount.decrementAndGet()
                }
            }
            if (workingCount.get() == 0) println("\tWE ARE ALL RESTING")
        }
}
Each flow can "report" thats its either
Resting
or
Working
. Each flow is completely independent of all other flows. When atleast one flows latest "report" was
Working
my merged state must be
Working
... Once all Flows latest report is
Resting
my merged state must be
Resting
Currently I have employed a WorkingCount to establish whether or not there is a
Working
Flow. I feel there must be a better solution than employing an AtomicCounter Is There? 🤔
w

wasyl

06/16/2021, 8:49 AM
You can use
combine
to get a new emission every time one of the combined flows emits:
val isRestingFlow = combine(flow1, flow2) { v1, v2 -> v1 is Resting && v2 is Resting }
t

Tower Guidev2

06/16/2021, 9:07 AM
@wasyl nice,
combine
is a clean solution, thanks
View count: 3