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

    CLOVIS

    04/17/2021, 12:41 PM
    If I have a
    SupervisorJob
    , how can I stop all its children without an exception? If I use
    supervisorJob.cancel()
    , an exception is thrown.
    a
    l
    z
    • 4
    • 7
  • m

    Muhammad Usman

    04/17/2021, 12:57 PM
    Hi how can result be returned from this extension function
    open class RootResponse<T>  {
        var success: Boolean = false
        var msg: String? = null
        var data: T? = null
    }
    fun <E, T : RootResponse<E>> CoroutineScope.launchCatching(blk: suspend () -> T): Result<E> {
        this.launch {
            kotlin.runCatching { blk() }
                .onSuccess {
                    if (it.success && it.data != null) {
                        Result.success(it.data)
                    } else {
                        Result.failure<String>(Throwable(it.msg))
                    }
                }.onFailure {
                    Result.failure<String>(it)
                }
        }
    
    }
    d
    r
    u
    • 4
    • 8
  • n

    Nowak

    04/20/2021, 7:51 AM
    Hi 🙂 I’m looking for some resources to learn Kotlin Coroutines. Could you recommend some good courses / tutorials / books which you know?
    l
    r
    j
    • 4
    • 6
  • s

    Scott Kruse

    04/20/2021, 4:43 PM
    Looking at this stack trace, curious if anyone has seen this / if it's a known issue:
    Fatal Exception: java.lang.StackOverflowError: stack size 8MB
           at kotlin.Result$Failure.<init>()
           at kotlin.ResultKt.createFailure(Result.kt:121)
           at kotlinx.coroutines.DebugStringsKt.toDebugString(DebugStrings.kt:18)
           at kotlinx.coroutines.internal.DispatchedContinuation.toString(DispatchedContinuation.kt:251)
           at kotlinx.coroutines.DebugStringsKt.toDebugString(DebugStrings.kt:16)
           at kotlinx.coroutines.CancellableContinuationImpl.toString(CancellableContinuationImpl.kt:506)
           at java.lang.String.valueOf(String.java:2827)
           at java.lang.StringBuilder.append(StringBuilder.java:132)
           at kotlinx.coroutines.ResumeAwaitOnCompletion.toString(JobSupport.kt:1414)
    u
    • 2
    • 3
  • u

    ursus

    04/21/2021, 12:04 AM
    suspend fun BarcodeScanner.processSuspending(image: ImageProxy): Barcode? {
    	return suspendCancelableCoroutine { continuation ->
    		continuation.invokeOnCancelation {
    			this.clear()
    		}
    
    		this.process(image)
    			.addOnSuccessListener { barcodes ->
    				val barcode = barcodes.someTransformation()
    				continuation.resume(barcode)
    			}
    			.addOnFailure { throwable -> 
    				continutaion.resumeWithException(throwable)
    			}
    	}
    }
    Would somebody mind looking at this if I do wrap a 3rd party callback library correctly? Its googles mlkit barcode scanner. Its my first time Also, what is the best pragmatic name of providing a suspend function if the "native" is called
    process()
    ?
    processSuspending()
    ? or some sort of
    await
    variant like
    awaitProcess()
    ? Also2, I don't need to apply dispatcher, since it provides callbacks, meaning it most likely has its own thread inside, right?
    e
    • 2
    • 5
  • p

    Patrick Ramsey

    04/21/2021, 12:27 AM
    Is there an API/pattern we should be using in place of CoroutineScope.actor, since that method (and anything to do with Channels) is marked as ObsoleteCoroutineApi?
    • 1
    • 1
  • l

    Lilly

    04/21/2021, 12:20 PM
    Is it possible to cancel a
    Flow
    manually but also waits until all launched coroutines in this flow have finished? I have a channel which is
    receivedAsFlow
    which in turn keeps the flow running until the channel is closed (by user or by exception). I would like to escape from this flow but also wait until all coroutines have finished...
    z
    a
    • 3
    • 31
  • k

    Kristian Frøhlich

    04/21/2021, 12:44 PM
    If i call this from another function the fireAndForgetSuspendFunction(arg) never runs. If i remove the delay it runs. How can i make it run in the background with the delay?
    b
    • 2
    • 8
  • e

    Erik

    04/21/2021, 4:07 PM
    I have a flow
    flow
    and a suspending function
    foo
    that I want to combine: when either produces a value, I want to combine the latest from both into a new emission.
    combine
    does that for flows, but
    foo
    is a suspending function that should be invoked only once. Also,
    combine
    doesn't emit until both sources have emitted at least once, but I want to emit either value as soon as it arrives and only start combining when both sources have produced a value. The type of the flow emissions and the return type of the suspending function are equal. I can think of some ways to do this, but there might be a very idiomatic and logical way, or even standard way of doing this. Any idea?
    b
    n
    • 3
    • 7
  • e

    Erik

    04/21/2021, 7:08 PM
    Let me rephrase my question (https://kotlinlang.slack.com/archives/C1CFAFJSK/p1619021225012300) with a runnable code example: https://pl.kotl.in/guoP8yGMg The output:
    Getting value
    tick 100
    tick 200
    0
    tick 300
    tick 400
    1
    Got value
    tick 500
    tick 600
    A2
    tick 700
    tick 800
    A3
    tick 900
    tick 1000
    A4
    The desired output
    Getting value
    tick 100
    tick 200
    0
    tick 300
    tick 400
    1
    Got value
    A1 // <-- immediately emit and combine the value and the last emission from the upstream flow
    tick 500
    tick 600
    A2
    tick 700
    tick 800
    A3
    tick 900
    tick 1000
    A4
    b
    u
    • 3
    • 16
  • m

    Michal Klimczak

    04/22/2021, 11:54 AM
    I have declared
    org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2-native-mt
    in deps, but my Kotlin Native code doesn't have access to runBlocking. Docs seems to say it should be there: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html. I also tried adding these to
    iosTest
    and it didn't work: •
    org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.4.2-native-mt
    •
    org.jetbrains.kotlinx:kotlinx-coroutines-core-common:1.4.2-native-mt
    • 1
    • 1
  • h

    Heikki Rauhala

    04/22/2021, 12:20 PM
    What does the note
    Note that the latest element is not emitted if it does not fit into the sampling window.
    mean in the documentation of
    Flow.sample
    ? https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/sample.html How can an element not fit in a sampling window? There will always be the next window, right? Unless the sampling is cancelled while there are un-emitted events in the latest window, but are there other situations where the latest event is not emitted?
    u
    • 2
    • 2
  • f

    Filip Wiesner

    04/22/2021, 6:54 PM
    Maybe a dumb question (EDIT: certainly dumb question 🙃) but how can I force app crash (Android) when child of
    SupervisorJob
    (viewModelScope) throws exception? My use case is that when debugging I want my app to crash whenever there is unhandled exception anywhere in my business logic but because
    viewModelScope
    is
    SupervisorJob
    , the coroutine is only getting cancelled. This behavior can be achieved by using
    Dispatchers.Main
    as context (presumably because it calls android
    UncaughtExceptionHandler
    ) but I how can I achieve this when using
    .Default
    or
    .IO
    dispatchers?
    👀 1
    z
    l
    +2
    • 5
    • 25
  • p

    pablisco

    04/23/2021, 9:32 AM
    I have this use case: There is a number of network calls that are sequential, so each needs to know about the previous one. My first thought was to use
    generateSequence
    however it doesn’t support suspend operations 🙃 Anyone knows of an alternative for such case?
    a
    l
    • 3
    • 15
  • m

    Martyna Maron

    04/23/2021, 12:21 PM
    Hello 👋 Struggling to understand this simple scenario - why does the app never finish? Both strings are printed fine, but
    main
    never returns 😕 All I need is for
    printSomethingWithDelay
    to execute on a background thread, with no new coroutine, how can I achieve that?
    fun main() {
    
        runBlocking {
            printSomethingWithDelay("something")
        }
        print("finished")
    }
    
    suspend fun printSomethingWithDelay(something: String) = withContext(AppDispatcher.appDispatcher){
        delay(1000)
        println(something)
    }
    
    
    object AppDispatcher {
    
        val appDispatcher = Executors.newFixedThreadPool(1).asCoroutineDispatcher()
    }
    s
    z
    l
    • 4
    • 7
  • e

    Erik

    04/23/2021, 2:41 PM
    I have a function like:
    @Synchronized fun foo()
    that now is being refactored to be
    @Synchronized suspend fun foo()
    (ℹ️ this is
    kotlin.jvm.Synchronized
    ). The synchronisation is still needed if I don't know the context in which this will be called, right? Is there a way to also get rid of the synchronisation? Can I change to a single threaded executor to ensure calls to this function happen sequentially? Or would I need a mutex? Or is it fine as-is? I'm asking because
    @Synchronized suspend fun foo()
    looks a bit non-coroutinesque to me.
    m
    e
    • 3
    • 12
  • g

    Guilherme Lima Pereira

    04/23/2021, 3:44 PM
    Hi everyone! In Kotlin Coroutines, if I have a function that returns a
    Deferred
    , launched on
    MainScope
    , should I be able to
    await
    until it finishes? I mean, should it block the
    Main Thread
    (that’s my goal, even though it sounds weird)?
    🙌🏽 1
    👀 1
    t
    e
    d
    • 4
    • 36
  • h

    Helio

    04/25/2021, 2:55 AM
    Hello 👋🏽 I’ve gotta a question here which I’m not entirely sure if it relates with Coroutines or Ktor. Apologies if this is the wrong channel. Well, I’ve recently updated Kotlin
    1.4.10 -> 1.4.32
    and Ktor
    1.4.2 -> 1.5.3
    . I was definitely expecting some of Unit tests to break due to compatibility and I’ve already fixed them. However, there are still 4 of them that I’m struggling to understand what could be wrong. When one of the unit tests starts, it adds an entity to a Global Variable with type
    mutableListOf<MyModel>()
    . I can confirm that the value was added successfully.
    ArrayList@XXXX
    . However, when one of the routes of my Ktor server attempt to read the value from that Global Variable, it is empty and the id of the object is now
    ArrayList@YYYY
    . It looks like when
    embeddedServer(…).start()
    is executed, it creates a new instance of the Global Object, hence it is empty. I’ve already tried many things, SynchronizeListOf, add the global variable into an object, but no matter what I do the reference of the GlobalObject into Ktor is always different. Would anyone be able to shed some light, please? Thanks heaps.
    :ktor: 1
    e
    l
    a
    • 4
    • 10
  • c

    christophsturm

    04/25/2021, 6:32 PM
    is
    GlobalScope.launch(Dispatchers.Unconfined) {
        coroutineScope {
    ...
       }
    }
    a good way to use structured concurrency in an async handler that does not know about coroutines?
    z
    l
    • 3
    • 17
  • b

    Bilagi

    04/26/2021, 4:00 PM
    Kotlin coroutines are using thread pools in background. How does coroutine can start executing in one thread, suspend execution, and resume on a different thread?
    z
    • 2
    • 2
  • m

    mzgreen

    04/26/2021, 5:11 PM
    So if Swift is first then does it mean that Kotlin Actors is a different thing? 🤔 https://twitter.com/clattner_llvm/status/1386728088633974785?s=19
    j
    z
    • 3
    • 2
  • c

    Conor Fennell

    04/26/2021, 9:36 PM
    Howdy, Have a beginner question around coroutines. I am using coroutines in a ktor project. And multiple coroutines can increment the same prometheus counter at the same time
    io.prometheus.client.Counter
    The prometheus Counter is a Java library. Is there any concurrency issues people would foresee? The prometheus implementation uses Compare and Swap operations so should be coroutine safe. But saying that, there is a thread hash code used for some accounting
    ThreadLocal()
    .
    static final ThreadLocal<int[]> threadHashCode = new ThreadLocal();
        static final Random rng = new Random();
        static final int NCPU = Runtime.getRuntime().availableProcessors();
        transient volatile Striped64.Cell[] cells;
        transient volatile long base;
        transient volatile int busy;
        private static final AtomicLongFieldUpdater<Striped64> CAS_BASE = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base");
        private static final AtomicIntegerFieldUpdater<Striped64> CAS_BUSY = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy");
    t
    u
    • 3
    • 3
  • z

    Zach Klippenstein (he/him) [MOD]

    04/26/2021, 11:30 PM
    GlobalScope
    is getting guard rails! My dream come true 😌
    🎉 2
    r
    b
    +4
    • 7
    • 34
  • s

    Slackbot

    04/27/2021, 11:58 AM
    This message was deleted.
    n
    • 2
    • 1
  • l

    Lilly

    04/27/2021, 7:48 PM
    I have a flow producer which emits continuously a specific byte to represent an idle mode. I would like to drop these bytes but log them every 2 or 3 seconds. Any ideas how to achieve this?
    d
    e
    • 3
    • 5
  • d

    Derek Ellis

    04/27/2021, 10:16 PM
    I'm having an issue where a flow isn't being collected and I can't for the life of me figure out why basic sealed class hierarchy:
    sealed class Update {
        object Success : Update()
        data class Progress(val message: String) : Update()
        data class Failure(val throwable: Throwable) : Update()
    }
    Success
    and
    Failure
    emissions are collected, but
    Progress
    ones are not applying only two operators:
    .filterNotNull()
    .transformWhile { update ->
       emit(update)
       update !is Update.Failure && update !is Update.Success
    }
    I've debugged and logged everywhere I could, and the
    Progress
    objects are definitely emitted by the flow, but they never make it to the
    .collect
    . Am I missing something really obvious here?
    b
    • 2
    • 22
  • n

    Norbi

    04/28/2021, 11:53 AM
    I have a question related to coroutines and blocking IO integration. For integrating with a blocking library, I need a conversion similar to this:
    // This is my asynchronous/suspending input stream
    interface AsyncInputStream {
        // This method has semantics similar to InputStream.read() but suspends instead of blocking
        suspend fun read(): Int
    }
    
    fun AsyncInputStream.asInputStream() = object : java.io.InputStream() {
        override fun read(): Int {
            return runBlocking { this@asInputStream.read() } // Is runBlocking() correct here?
        }
    }
    If I understand correctly, using
    runBlocking
    is incorrect because it "should not be used from a coroutine", and
    AsyncInputStream.asInputStream()
    would possibly be called from coroutines. Thanks.
    z
    u
    • 3
    • 4
  • g

    gts13

    04/28/2021, 3:00 PM
    this might be a noob question but today I realized that StateFlow doesn’t work very well (or better saying intentionally doesn’t work) with Lists. So if we have the below (very rough example)
    data class ViewItem(
      val id: String,
      val title: String,
      var description: String = "" // yes a var
    )
    
    private val _items: MutableStateFlow<List<ViewItem>> = MutableStateFlow(emptyList())
    val metrics: StateFlow<List<ViewItem>> = _metrics
    
    _metrics.value = _metrics.value.toMutableList().find { // some predicate }?.description = "a new title"
    The
    _metrics
    won’t emit the new value (which is actually a change in the
    ViewItem
    object. Am I right or I am missing something here? And If I am right, in order to solve the above “issue” I need to use
    Channel
    or is there any other way with
    StateFlow
    ?
    c
    f
    • 3
    • 12
  • s

    Satyam Agarwal

    04/28/2021, 8:00 PM
    Hei. @elizarov (apologies for tagging you directly) I wanted to get your rationale over
    GlobalScope.launch { … }
    I read this article https://elizarov.medium.com/the-reason-to-avoid-globalscope-835337445abc which makes sense, and I almost always use
    withContext(AppropriateDispatcher) { … }
    to offload heavy jobs. I have a ktor server that receives around 260 req/sec and logs request and responses while receiving and responding, along with actual response. This is done via an interceptor. Now I don’t care much about logging, so I was thinking to do something like
    GlobalScope.launch(MDCContext()) { interceptor.request.log(...) }
    so that logging is eventually done, but the interceptor can
    proceed()
    immediately. In fact, I was thinking to do this to pretty much every logging, Do you think it is a good way of doing the intention. What can be the consequences in regards to threads and CPU if a lot of logging suddenly starts offloading to GlobalScope ? Anyone can help me as well 🙂 Any and all feedback is much appreciated.
    b
    z
    +4
    • 7
    • 13
  • u

    ursus

    04/29/2021, 3:09 AM
    Folks who inject CoroutineScope, as in App scope, to keep the suspend functions running no matter the ui, Do you expose regular or suspend functions for such component?
    class Foo(coroutineScope) {
       fun bar() {
          coroutineScope.launch {
             ...
          }
       }
    }
    This however does not compose as its not s suspend function 😑 What to do if a blocking function is needed for some legacy component? If it were a suspend function, that legacy component might call it from within a runBlocking block If however its a plain function, now I need to add a barBlocking as well to the api, which is ..ughh, not scaling well
    s
    u
    • 3
    • 5
Powered by Linen
Title
u

ursus

04/29/2021, 3:09 AM
Folks who inject CoroutineScope, as in App scope, to keep the suspend functions running no matter the ui, Do you expose regular or suspend functions for such component?
class Foo(coroutineScope) {
   fun bar() {
      coroutineScope.launch {
         ...
      }
   }
}
This however does not compose as its not s suspend function 😑 What to do if a blocking function is needed for some legacy component? If it were a suspend function, that legacy component might call it from within a runBlocking block If however its a plain function, now I need to add a barBlocking as well to the api, which is ..ughh, not scaling well
s

streetsofboston

04/29/2021, 4:02 AM
Not sure why a CoroutineScope would need to be injected. Injection of a CoroutineContext (eg a Dispatcher) makes sense (especially for the benefit of writing unit tests), but why injecting a CoroutineScope?
u

uli

04/29/2021, 7:35 AM
to keep the suspend functions running no matter the ui
@streetsofboston I see, you are not questioning why a Scope, but why to inject it. 🙂
@ursus what do you mean by
This however does not compose
. What is your issue with the non-suspending approach?
u

ursus

04/29/2021, 7:47 AM
for example when i need a to make it into a blocking function .. like in firebase messaging service; if it were suspending, i'd just call it in runBlocking
fun FirebaseMessagingService.onMessageReceived() {
    runBlocking { thingThatWouldBeLaunchedInFoo() }
}
I also create it privately, but I've seen folks sharing/injecting the scope
View count: 12