https://kotlinlang.org logo
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
  • s

    SrSouza

    05/17/2020, 5:29 PM
    HI folks, what is the difference of
    Channel.offer
    and
    Channel.send
    , I know that send suspend and offer don't, but what is the usage difference?
    s
    g
    • 3
    • 2
  • z

    zak.taccardi

    05/17/2020, 6:21 PM
    What would be the idiomatic way to subscribe to
    flowB
    when
    val flowA: Flow<Boolean>
    emits
    true
    , and unsubscribe from
    flowB
    when
    flowA
    emits
    false
    ?
    o
    t
    g
    • 4
    • 8
  • j

    Joffrey

    05/18/2020, 7:31 AM
    Hi guys, I often find it pretty useful to catch low-level exceptions and wrap them into more meaningful higher-level exceptions:
    try {
       // some suspending operations to connect to web socket
    } catch(e: Exception) {
       throw WebSocketConnectionFailedException("meaningful high-level msg", e)
    }
    But when coroutine machinery like
    withTimeout
    is used around this code, it doesn’t behave as expected (we’re expecting a
    TimeoutCancellationException
    but get another one). To solve this problem, I add an extra catch to rethrow
    CancellationException
    as-is, but it doesn’t feel right…
    try {
       // so some operations to connect to web socket
    } catch(e: CancellationException) {
       throw e // no wrapping here
    } catch(e: Exception) {
       throw WebSocketConnectionFailedException("meaningful high-level msg", e)
    }
    Is there a better / built-in way to do this?
    m
    • 2
    • 1
  • t

    trathschlag

    05/18/2020, 11:29 AM
    fun scroll() = flow {
      try {
        // do stuff
      } finally {
        withContext(NonCancellable) { suspendingCleanUpFunction() }
      }
    }
    This does obviously not work. What would be the correct pattern here?
    m
    e
    • 3
    • 3
  • e

    Erik

    05/18/2020, 2:58 PM
    I'm confused about the following quote from the
    Job
    documentation (https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-job/index.html):
    Normal cancellation of a job is distinguished from its failure by the type of its cancellation exception cause. If the cause of cancellation is CancellationException, then the job is considered to be cancelled normally. This usually happens when cancel is invoked without additional parameters. If the cause of cancellation is a different exception, then the job is considered to have failed. This usually happens when the code of the job encounters some problem and throws an exception.
    From the first sentence I conclude that a coroutine's
    CancellationException
    may have a
    cause
    . From the second sentence I conclude that the
    cause
    may be yet another
    CancellationException
    , 😕 am I right? And from the fourth sentence I conclude that, if failed, I will receive a
    CancellationException
    with a
    cause
    that is not a
    CancellationException
    , am I right? So: normally, can a
    CancellationException
    have another
    CancellationException
    as its
    cause
    ? If so, can this lead to deep nesting of
    CancellationException
    instances? And, if so, should traverse this chain of cancellation exceptions in search for a different type of exception to determine if this was a failure or normal cancellation?
    z
    f
    e
    • 4
    • 12
  • d

    David Glasser

    05/18/2020, 11:26 PM
    I have a test where I want to launch a few jobs, wait until they hit their first suspend point, and then do something else. How can I do that reliably?
    • 1
    • 1
  • s

    Stephan Schroeder

    05/19/2020, 8:25 AM
    Is
    runBlocking
    an expensive operation? The docs seem to suggest that it’s a good idea to use it once in the main-method and than stay in suspend-country for the rest of the codebase. But how about sprinkling in a bit of concurrent computation here and there with snippets like this:
    val (a, b) = runBlocking(Dispatchers.Default) {
            val aDeferred = async {getA()}
            val aDeferred = async {getB()}
            return@runBlocking aDeferred.await() to bDeferred.await()
    }
    Doable or bad idea?
    o
    g
    +3
    • 6
    • 57
  • t

    Tolriq

    05/19/2020, 12:31 PM
    What would be the proper way to have a continuous source of elements that one could take elements from without closing? Like a pool of 10 items that require heavy computation, that is only refilled by the correct amount each time one is removed.
    g
    • 2
    • 64
  • v

    Vsevolod Tolstopyatov [JB]

    05/19/2020, 12:47 PM
    📣 📣 📣 kotlinx.coroutines 1.3.7 release: • Fixed problem that triggered Android Lint failure • New
    Flow.cancellable()
    operator for cooperative cancellation • Emissions from
    flow
    builder now check cancellation status and are properly cancellable • New
    currentCoroutineContext
    function to use unambiguously in the contexts with
    CoroutineScope
    in receiver position •
    EXACTLY_ONCE
    contract support in coroutine builders. • Various documentation improvements.
    👍 1
    🎉 27
    g
    • 2
    • 2
  • t

    taer

    05/19/2020, 3:52 PM
    Funny that chunked question just came up. I'm working on a small impl myself, and had a question on it. https://github.com/Kotlin/kotlinx.coroutines/pull/1558/files#diff-aa50430f04c34e0e106abd538b1918fcR84 If the upstream flow throws an exception, I want to go ahead and flush the buffered results, then rethrow the exception. I dont think this code does that, and I'm struggling to find the right way to accomplish it cleanly.
    • 1
    • 1
  • t

    taer

    05/19/2020, 4:32 PM
    Is there a better way to only send a "completion message" on a successful completion of flow when using a cancel? in this case, batchMeetings is my own impl of
    flow.chunked()
    var caughtException = false
            val batches = batchResults(inputFlow, chunkSizePerMessage)
                .map { createResults(it) }
                .catch {
                    caughtException=true
                    emit(Results.TerminateWithError(it))
                }
            emitAll(batches)
            if(!caughtException) {
                emit(Results.SuccessfulFinish())
            }
    Ideally, the Successful finish would only be sent on no exceptions from the upstream flow. That
    var caughtException
    seems ugly. Is there a cleaner way?
    e
    • 2
    • 15
  • l

    Luis Munoz

    05/19/2020, 8:42 PM
    How do I implement two way generator with kotlin coroutines? For example in javascript you would do:
    function* generatorFunction(i) {
       yield i
       yield i +1
    }
    
    let gen = generator(5)
    gen.next() //  value=5, done=false
    gen.next() //  value=6, done=false
    // WHAT I WANT IS THIS
    gen.next(100) // <-- here I pass value and get back another value at next yield point
    so in generator it would be let x = yield i to get the input value
    o
    a
    • 3
    • 10
  • r

    Rob Elliot

    05/19/2020, 9:36 PM
    Hi all, I found myself writing this, then was confused that it wasn’t in the coroutines library already - is it a bad idea / implementation?
    suspend fun <T> Iterable<T>.forEachParallel(
      f: suspend (T) -> Unit
    ) {
      coroutineScope {
        forEach { t ->
          launch {
            f(t)
          }
        }
      }
    }
    o
    • 2
    • 2
  • t

    tmg

    05/20/2020, 8:52 AM
    Hi guys, quick question, does
    async
    executed inside a
    coroutineScope
    finishes before the block exits? (i mean,
    coroutineScope
    waits
    async
    , just like it does for
    launch
    )
    m
    g
    • 3
    • 17
  • d

    Dsittel

    05/20/2020, 9:50 AM
    Hi guys, i have problems with some corner cases here within this scope.
    Unbenannt
    e
    • 2
    • 3
  • l

    Luis Munoz

    05/20/2020, 2:49 PM
    Can someone explain @RestrictsSuspension in plain english. Why is it needed, is there a performance benefit to using it?
    /**
     * Classes and interfaces marked with this annotation are restricted when used as receivers for extension
     * `suspend` functions. These `suspend` extensions can only invoke other member or extension `suspend` functions on this particular
     * receiver and are restricted from calling arbitrary suspension functions.
     */
    @SinceKotlin("1.3")
    @Target(AnnotationTarget.CLASS)
    @Retention(AnnotationRetention.BINARY)
    public annotation class RestrictsSuspension
    s
    c
    • 3
    • 6
  • r

    rocketraman

    05/20/2020, 9:12 PM
    Has anyone looked at / benchmarked the GC overhead of coroutine suspend and resume?
    o
    l
    • 3
    • 25
  • b

    bbaldino

    05/20/2020, 11:03 PM
    Say I've got a class
    Foo
    (which I don't control) which exposes a field
    incoming: ReceiveChannel<String>
    , and I have a custom type
    data class MyType(val str: String)
    and I want to add an extension field to
    Foo
    to expose a field
    incomingMyType: ReceiveChannel<MyType>
    . What's the best way to wrap the existing channel and map it to produce instances of
    MyType
    containing the
    String
    values? I have something equivalent to the code below working, but wondering if there's any better way. Maybe something with
    Flow
    ?
    val Foo.incomingMyType: ReceiveChannel<MyType>
        get() = produce {
            for (str in incoming) {
                send(MyType(str))
            }
        }
    a
    o
    o
    • 4
    • 11
  • d

    dave08

    05/21/2020, 8:04 AM
    StateFlow<Unit?>
    can't be used to represent clicks since it's conflated right (unless a new object is created for each emission...)? But
    SharedFlow
    will?
    l
    s
    • 3
    • 7
  • m

    myanmarking

    05/21/2020, 9:58 AM
    "Invokes the given action when the given flow is completed or cancelled, passing the cancellation exception or failure as cause parameter of action" -> Can some1 explain this documentation for flow.onComplete for me. I don't understand the last part "or failure as cause parameter of action", since an uncaught exception abort the stream. What is this failure refering to ?
    j
    • 2
    • 5
  • d

    Dsittel

    05/21/2020, 10:35 AM
    compile says: required FlowCollector
    having problems to get this running in a unit test
    g
    • 2
    • 5
  • a

    Archie

    05/21/2020, 2:47 PM
    is there a way to not always add
    @ExperimentalCoroutinesApi
    all the time when using coroutines flow?
    e
    • 2
    • 2
  • k

    kevin.cianfarini

    05/22/2020, 6:18 PM
    How would I go about having a
    CoroutineScope
    that automatically restarts jobs that have failed? Maybe with exponential backoff?
    z
    o
    u
    • 4
    • 10
  • d

    Daniel Lukic

    05/23/2020, 2:30 PM
    bit of a weird question.. is there anything like persisting a coroutine? like, its current state? and restoring it, to continue were it was before? or anything that points in this direction? could that even make any sense? a bit weird, right? just an experimental thought in some android project.. context is backgrounding the app during some more involved flow.. and restoring it.. without having to do this on a - idk view model or something - level.. and instead just saying "resume the coroutines".. low priority.. but any thoughts on this appreciated.. 😊
    d
    l
    • 3
    • 3
  • v

    voben

    05/24/2020, 6:24 PM
    Does flow have an operator similar Rx’s `buffer(long timespan, TimeUnit unit)`and what is it called?
    l
    • 2
    • 1
  • n

    napperley

    05/25/2020, 11:55 PM
    Noticed that the KotlinX Coroutines library provides artifacts for the linuxX64 target but not for the other Linux targets (eg linuxArm32Hfp). Why is linuxX64 the only supported Linux target?
    d
    l
    • 3
    • 11
  • l

    Luis Munoz

    05/26/2020, 8:09 AM
    How do I do a channel or flow Fan-out where the same value is received by all collectors or receivers? Documentation for channel fan-out just shows fan-out where the work is distributed, for flow share seems to be work in progress. What solutions are available now?
    a
    z
    • 3
    • 2
  • m

    Marc Knaup

    05/26/2020, 9:17 AM
    I’m still at war with scopes and contexts 😅 Let’s say I have a
    sessionCoroutineContext
    that gets canceled once the user has logged out (i.e. the session is closed). I have a
    MessageRepository
    that must only be used while the session is open. Do I now have to wrap every single
    suspend fun
    in my
    MessageRepository
    with
    withContext(sessionCoroutineContext) { … }
    so that they cancel once the session is closed? Some context: I still have a scenario where an Android activity is collecting a flow in its
    viewModelScope
    . An element is collected after the user’s session was closed. The collector uses the repository which in turn uses the database which in turn tries to access files that no longer exist because the session is closed -> boom. The idea is to have repository and database properly bound to the session lifecycle so that it doesn’t even try to do anything when the session is gone and throws a cancellation up to the collector.
    h
    • 2
    • 4
  • g

    gotoOla

    05/26/2020, 9:18 AM
    Could someone explain to me what's going on here? I get errors on the suspending calls? Is that due to the sequence or why would I lose my coroutine-context from the "suspend" function?
    private suspend fun processAndSend() {
        documentService.getDocuments(reference) // returns a Sequence<Documents>
                .chunked(10)
                .map { chunkedDocuments ->
                    val processedDocuments = httpClient.processDocuments(chunkedDocuments) // compile error, suspending call
                    queueSender.send(processedDocuments) // compile error, suspending call
                }
    }
    
    // compile error = Suspension functions can be called only within coroutine body
    a
    • 2
    • 6
  • m

    Marc Knaup

    05/26/2020, 9:31 AM
    Also, when exactly are coroutines checked for cancelation? Will a suspending function call check for cancelation before the function implementation is invoked? Will
    withContext
    check for cancelation upon before and/or after invoking
    block
    ? Will
    yield
    check for cancelation immediately or on/after dispatch?
    b
    l
    +2
    • 5
    • 11
Powered by Linen
Title
m

Marc Knaup

05/26/2020, 9:31 AM
Also, when exactly are coroutines checked for cancelation? Will a suspending function call check for cancelation before the function implementation is invoked? Will
withContext
check for cancelation upon before and/or after invoking
block
? Will
yield
check for cancelation immediately or on/after dispatch?
b

bezrukov

05/26/2020, 10:07 AM
Will a suspending function call check for cancelation before the function implementation is invoked?
it's heavily depends on suspend fun implementation, by default suspend fun is not cancellable out of the box, so it needs to be designed to support cooperative cancellation (e.g. use built-in primitives or check for coroutine state).
Will 
withContext
 check for cancelation upon before and/or after invoking 
block
?
Should be both in general
Will 
yield
 check for cancelation immediately or on/after dispatch?
yield
will check it immediately, but will also resumed with exception if job was cancelled before re-dispatching. Also consider
ensureActive
for checking for cancellation in your non-cancellable code
m

Marc Knaup

05/26/2020, 10:15 AM
Thank you for the clarification! I didn’t know about
ensureActive
. That seems helpful given that
suspend fun
don’t check for cancelation by default (unless it calls others that do). Do you happen to know a good open source example/library/app that properly manages various scopes & contexts and thus can serve as guidance?
l

louiscad

05/26/2020, 12:08 PM
withContext
since I don't recall which kotlinx.coroutines version does check for cancellation before and after invoking block using its given context (which, in case of
NonCancellable
, will be prevented).
u

uli

05/26/2020, 2:28 PM
I'd expect all suspension points to check for cancelation, at least on resume. There are not so many ways to cause suspension:
Suspend(Cancelable)Coroutine
,
yield
,
withContext
,
await
, and funs calling one of the above. what did i forget?
o

octylFractal

05/26/2020, 5:10 PM
all suspension points can't check cancelation because suspend (Continuations) is a language feature, but coroutines are a library implemented on top of that e. g. sequences are suspend, but they do not cooperate with coroutines and do not dispatch, or handle cancelation. additionally, calling a suspend function will not result in a cancelation check
👍 1
another example is (until recently) Flow basic mechanisms did not check for cancelation
l

louiscad

05/26/2020, 7:26 PM
@octylFractal coroutines are not a library, kotlinx.coroutines is, and as of Kotlin 1.3, it brings cancellation support with
Job
. FYI, the "x" in kotlinx stands for extension.
o

octylFractal

05/26/2020, 8:14 PM
alright, I suppose that's true, but it doesn't change what I said -- cancellation is not a concept in the stdlib, so not all suspension points check for it
"kotlinx.coroutines" is what brings cancellation to the table
l

louiscad

05/26/2020, 8:58 PM
That's true.
m

Marc Knaup

05/27/2020, 7:16 AM
Interesting and makes sense. Thanks @octylFractal and @louiscad!
View count: 1