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

    Astronaut4449

    02/19/2020, 6:55 PM
    I have a comment an the coroutine channel API. Currently the
    Channel
    constructor takes a
    capacity
    argument of type Int.
    capacity
    is also used to define the type of the channel by the use of magic constants such as RENDEVOUS=0, BUFFERED=-2, UNLIMITED=Int.MAX_VALUE.
    val c1 = Channel<Int>(capacity = 15)
    val c2 = Channel<Int>(capacity = RENDEVOUS) // dislike
    Kotlin has the great feature of sealed classes. Wouldn't it be better to have an API like:
    // Limited(capacity: Int) and object Rendevous belong to sealed class ChannelType
    val c1 = Channel<Int>(type = Limited(15))
    val c2 = Channel<Int>(type = Rendevous) // Rendevous is an object here
    👍 4
    ➕ 14
    e
    • 2
    • 3
  • k

    kevinherron

    02/19/2020, 10:20 PM
    anybody else rarely able to get a breakpoint to work inside a suspending function?
    e
    m
    b
    • 4
    • 9
  • j

    Jakub Gwóźdź

    02/20/2020, 9:44 AM
    Hi. I have problems limiting the thread pool in coroutines: I have my simple helper function:
    fun <T, R> runConcurrently(nThreads: Int, params: Collection<T>, op: suspend (T) -> R): List<R> {
        return runBlocking {
            Executors.newFixedThreadPool(nThreads).asCoroutineDispatcher().use { pool ->
                params.map { p -> async(pool) { op(p) } }
            }.awaitAll()
        }
    }
    and it works well when I DON'T use any yielding call inside my
    op()
    , e.g:
    runConcurrently(3, (1..8).toList()) { param ->
        counter.increase()
        val sleepTime = 1000L / param
        println("Started $param in thread ${Thread.currentThread().name}, counter is $counter, sleepTime is $sleepTime")
    
        Thread.sleep(sleepTime)
        println("Stopping $param in thread ${Thread.currentThread().name}")
        counter.decrease()
    }
    But as soon as I call any suspending function inside, e.g. change
    Thread.sleep()
    to
    delay()
    , it switches rest of execution to DefaultExecutor, and my pool is not limiting anymore. What am I doing wrong? And what is current best way to limit thread pool? I know newFixedThreadPool is deprecated, but there is no alternatives afaik.
    • 1
    • 3
  • m

    magnumrocha

    02/20/2020, 4:33 PM
    is there are way to close a Channel (
    channelFlow
    or
    callbackFlow
    ) without sending a error to the consumers?
    s
    k
    • 3
    • 65
  • m

    magnumrocha

    02/20/2020, 4:35 PM
    I mean, when a I close my
    channelFlow
    even I don't passing some Exception, internally the flow will throw a
    CloseSendChannelException
    v
    • 2
    • 1
  • j

    Joe

    02/20/2020, 11:44 PM
    I'm using
    java.util.stream.Stream.consumeAsFlow()
    to process a stream as a flow. Sometimes, it appears that the
    finally { stream.close() }
    block is not getting called (possibly on certain cancellation / error conditions?) (confirmed by duplicating the StreamFlow class and adding a log statement), although if I add an
    onCompletion {}
    to the returned flow, that block does get called even when the finally gets skipped. Anything that can explain this behavior? Will probably move back to using the
    onCompletion
    to close the Stream in the meantime though.
    l
    • 2
    • 3
  • c

    Chantry Cargill

    02/21/2020, 2:12 PM
    In Spring WebFlux, when dealing with blocking IO, I assume the correct dispatcher to use is Dispatchers.IO. However, when using non-blocking IO, should we be using Default or Unconfined? I’m particularly thinking about async blocks like below.
    @GetMapping("/things")
        suspend fun getThings() = coroutineScope {
            val thing = async {
                suspendingCall()
            }
    
            val anotherThing = async {
                suspendingCallAgain()
            }
    
            listOf(thing.await(), anotherThing.await())
        }
    l
    z
    • 3
    • 7
  • l

    Leon K

    02/21/2020, 2:18 PM
    Hey! I have a variable that I need Synchronized access to from two functions: a
    suspend
    fun and a non-suspending function. I cannot just do
    @Synchronized
    on the blocking one and use
    Mutex
    on the suspend-one as these don't exclude each other, such that there is still the posibility of two concurrent accesses. It seems as tough
    Mutex
    is not usable from non-blocking code, and
    @Synchronized
    doesn't help with `suspend fun`s. what's the best approach here?
    d
    u
    +2
    • 5
    • 13
  • r

    rkeazor

    02/22/2020, 9:15 PM
    Whats the best way to integrate a Broadcast Channel and Flow together?So that you have a hot flow, that collects anything that the broadcast channel emits
    a
    l
    b
    • 4
    • 10
  • b

    Brendan Weinstein

    02/24/2020, 9:10 AM
    How do I synchronize the dispatchAction function below so that it only starts sending items once there is a downstream collector? onStart unfortunately get called right before collect.
    class StateMachine(val scope: CoroutineScope) {  
    
      private val inputActions: BroadcastChannel<Rankings.Action> = BroadcastChannel(Channel.BUFFERED)
      private var isInitialized = atomic(false)
    
      init {
        scope.launch {
          inputActions.asFlow()
            .onStart { isInitialized.value = true //onStart hook is called just before collect gets called }
            .collect { action ->
              //handle action
            }
          // CANNOT CALL FUNCTION HERE BECAUSE `collect` SUSPENDS
        }
      }
    
      fun dispatchAction(action: Rankings.Action) = scope.launch {
        while(!isInitialized.value) {
        }
        inputActions.send(action)
      }
    }
    k
    u
    • 3
    • 12
  • m

    Michael Friend

    02/24/2020, 6:33 PM
    I want to be able to attach a resettable timeout on a job where basically I give a timeout and a channel and whenever the channel is sent a value then the timeout is reset. Is there a common practice for something like this? I was thinking of writing an extension function on Job but im not sure how i wanna approach it.
    e
    • 2
    • 1
  • m

    momrak

    02/25/2020, 7:02 AM
    Hi! I'm rather new to working with coroutines and I have a question regarding testing them. I have a service similar to this
    fun handleDelete(extIds: List<String>) {
            val ids = someClient1.getInternalIds(extIds) // get deleteable IDs
    
            try {
                runBlocking(<http://Dispatchers.IO|Dispatchers.IO>) { // use IO dispatcher as someClient2 makes a call to some remote service. 
                    ids.forEach{ launch { someClient2.deleteId(it) } }
                }
            } catch (e: Exception) {
                handleException(e)
            }
        }
    and I want to test it. My team uses Mockito and not Mockk, if that makes any difference. Maybe the test does not make sense, but as I am not very familiar with coroutines I want to test that these are run correctly in paralell and that they exit the runBlocking block after they're all done. So I was thinking of mocking the responses from
    someClient2
    so that say i have
    extIds = listof("123", "456")
    and the calls take respectively 500ms and 750ms, I want to check that in total this function does not use much more time than ~750ms and not (500+750)=1250ms. Is this possible using Mockito? And is it actually a useful test? 🤔
    o
    • 2
    • 10
  • s

    Slackbot

    02/25/2020, 11:19 PM
    This message was deleted.
    z
    k
    k
    • 4
    • 7
  • u

    ursus

    02/26/2020, 3:52 AM
    I hate flatmapping singles, sooo hurry up 😄
    t
    • 2
    • 1
  • j

    Jason

    02/26/2020, 10:33 AM
    How to implement timer (looping call) in Kotlin coroutine like
    rxJava
    Single.timer(INTERVAL_SECONDS, TimeUnit.SECONDS)
          .flatMap{ // call API }
          .repeat()
          .subscribeOn(<http://Schedules.io|Schedules.io>())
    I heard someone mentioned using
    flow
    . It look likes
    while(true){
        // call 
        // delay(intervalMili)
    }
    So I think it’s not looking good .
    c
    m
    k
    • 4
    • 6
  • b

    bod

    02/26/2020, 2:01 PM
    Hello, World! Let's say I have a fun to which I want to pass a lambda - and in certain cases it would make sense to pass it a
    suspend
    lambda. I think there's 2 way I can do this: • have 2 different functions: something like
    handle(onSuccess: () -> Unit)
    and
    handleSuspend(onSuccess: suspend () -> Unit)
    • just have the suspend version and it can also accept a regular (non suspend) lambda My question is is there a performance penalty (or otherwise) in doing the second option?
    l
    k
    • 3
    • 3
  • l

    LastExceed

    02/26/2020, 2:10 PM
    why can't initializers be
    suspend
    ?
    s
    a
    • 3
    • 6
  • a

    Animesh Sahu

    02/26/2020, 2:21 PM
    What could be the best approch to call a suspension function inside a coroutine exception handler?
    val handler = CoroutineExceptionHandler { context, exception ->
    	Log.d("exception", exception.message ?: "", exception)
    	suspensionFunc() // <--- This part, such as for calling a network requests.
    }
    What i thought of are: 1. Wrap the context with a
    CoroutineScope()
    and then launch with it. 2. Call using
    runBlocking{}
    , but isn't best idea cause it could affect app performance specially if ran on Main threads 3. Use
    GlobalScope()
    4. Use
    GlobalScope()
    but launch to IO dispatcher.
    e
    • 2
    • 9
  • e

    Esa

    02/27/2020, 8:58 AM
    This will create 1 job for every element of the list, regardless of how large the list is, which will attempt to then run in parallel. May or may not be the behaviour you want.
    t
    k
    • 3
    • 6
  • m

    Maurice Jouvet

    02/27/2020, 9:44 AM
    Do you know how could I restrain the number of threads? I would like to execute a task (fetch & sync data) with only 5 threads. Here what I have done so far, but it’s not working for me.
    val entryCoroutineContext = newFixedThreadPoolContext(5, "sync_entry_fixed")
            CoroutineScope(entryCoroutineContext).launch {
                val syncEntries = syncEntryDao.findAll()
    
                syncEntries.forEach { syncEntry ->
                    Timber.d("Got this data to sync: $syncEntry") // All data are shown here I exepct just 5 to 5
                    syncEntry.locked = true
                    syncEntryDao.update(syncEntry)
    
                    val response = webServices.syncEntriesCoroutine(clientName, syncEntry.date, syncEntry.blueAppId, syncEntry.offset, syncEntry.limit)
                    if (response.isSuccessful) {
                        ...
                    }
                }
    r
    j
    d
    • 4
    • 16
  • c

    corneil

    02/27/2020, 11:55 AM
    I need some advice: I have done a project that provides an FSM implementation and a DSL for defining the FSM. As part of the DSL you can provide lambdas for the actions the FSM will invoke. Will it be best to provide the user with a choice up front as to whether all actions will be suspend functions or is there an elegant way that I may not have considered to have a lambda that may or may not be a suspend function and the decision on how to use is is made later? The primary repo can be found here: https://github.com/open-jumpco/kfsm
    e
    c
    l
    • 4
    • 10
  • v

    Vlad

    02/28/2020, 10:49 AM
    Whats the best way to efficiency suspend coroutine indefinitely?
    delay(Long.MAX_VALUE)
    or
    Mutex(true).run { lock() }
    or something else?
    d
    t
    +4
    • 7
    • 11
  • k

    KotlinIsMyFav

    02/28/2020, 5:44 PM
    I am using kotlin version 1.1.3-2 .Are coroutines supported on it?
    l
    r
    • 3
    • 7
  • k

    KotlinIsMyFav

    02/28/2020, 10:06 PM
    I updated to kotlin 1.3.61 and seeing errors like: Cannot access built-in declaration 'kotlin.Unit'. Ensure that you have a dependency on the Kotlin standard library . Cannot access built-in declaration 'kotlin.collections.MutableSet'. Ensure that you have a dependency on the Kotlin standard library
    l
    • 2
    • 2
  • d

    David Glasser

    02/29/2020, 2:43 AM
    I'm making a flow that produces a list of files from Google Cloud Storage through running paginated executions. The actual RPCs should be in Dispatchers.IO (I think!). I'm not sure if I'm supposed to use withContext for this or flowOn. What I have is:
    fun listFiles(bucket: String, prefix: String): Flow<Blob> = flow {
    		var page = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
    			gcs.list(bucket, BlobListOption.prefix(prefix))
    		}
    		while (true) {
    			emit(page)
    			if (!page.hasNextPage()) {
    				break
    			}
    			page = withContext(<http://Dispatchers.IO|Dispatchers.IO>) { page.nextPage }
    		}
    	}.flatMapConcat { page ->
    		page.values.asFlow()
    	}
    but I don't know if that is right
    l
    • 2
    • 3
  • v

    Vsevolod Kaganovych

    03/01/2020, 8:41 AM
    Guys. My question is about Clean Architecture and Flow. How we used it with
    RxJava
    perviously: presentation layer knows nothing about
    RxJava
    , we only pass callback from
    UseCases
    with Success or Error. But now we switch to
    Flow
    a here’s what I need to understand: I don’t want a
    ViewModel
    to know anything about the
    Flow
    , so I pass a
    job
    to a
    ViewModel
    to unsubscribe from it and callbacks according to state and use
    mainScope()
    function in every
    UseCase
    , so I don’t use a
    ViewModelScope
    . I need to know your thoughts about it. By doing this I’m sure that if I need to switch in future to other framework than
    coroutines flow
    I would do it pretty smoothly.
    d
    • 2
    • 1
  • j

    Joan Colmenero

    03/02/2020, 12:42 PM
    Is there any way to combine 2 calls like this :
    val time = measureTimeMillis {
        val one = async { doSomethingUsefulOne() }
        val two = async { doSomethingUsefulTwo() }
        println("The answer is ${one.await() + two.await()}")
    }
    println("Completed in $time ms")
    because if for instance one.await() crashes what will happen? or if both crashes, is there any way to handle these errors? Or in case I just want to continue with the execution instead of adding the values just printing them, is there any way to print the first one (the one that did not crash) and the others doesn't (if it crashes)?
    m
    s
    l
    • 4
    • 6
  • m

    Mohamed Ibrahim

    03/02/2020, 3:52 PM
    I have a
    Flow<Product>
    which emits one by one, how I make it to collect those in list so I could receive a list in
    collect()
    l
    s
    • 3
    • 14
  • l

    Luis Munoz

    03/02/2020, 4:07 PM
    I am uncertain when to use suspend fun verses CoroutineScope extension function, is there a documentation that says why to prefer one over the other?
    s
    • 2
    • 3
  • j

    Joan Colmenero

    03/03/2020, 10:12 AM
    I'm trying to remove the
    withContext
    from my viewModel and I'm planning to put it on the
    usecase
    /
    repository
    something like this
    launch{
     updateView()
     withContext(<http://Dispatchers.IO|Dispatchers.IO>){
       doLogin(username,password)
     }
     updateView()
    }
    This is how I'm doing it now ^ Then if I want to remove the
    withContext(<http://Dispatchers.IO|Dispatchers.IO>)
    I can do it like this
    suspend fun doLogin(usernarme: String, password: String) = <http://Dispatchers.IO|Dispatchers.IO> { repo.doLogin(username,password)... }
    So, is there any way to test it correctly? I'm using
    mockK
    so, I know with
    coEvery
    is going to work, but is it safe to do not put
    Dispatchers.Uncofined
    for testing purposes? Also do you think it's a good idea to do not change context on viewModel and then just do this
    launch {
     updateView()
     doLogin(username,password)
     updateView()
    }
    s
    t
    • 3
    • 4
Powered by Linen
Title
j

Joan Colmenero

03/03/2020, 10:12 AM
I'm trying to remove the
withContext
from my viewModel and I'm planning to put it on the
usecase
/
repository
something like this
launch{
 updateView()
 withContext(<http://Dispatchers.IO|Dispatchers.IO>){
   doLogin(username,password)
 }
 updateView()
}
This is how I'm doing it now ^ Then if I want to remove the
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
I can do it like this
suspend fun doLogin(usernarme: String, password: String) = <http://Dispatchers.IO|Dispatchers.IO> { repo.doLogin(username,password)... }
So, is there any way to test it correctly? I'm using
mockK
so, I know with
coEvery
is going to work, but is it safe to do not put
Dispatchers.Uncofined
for testing purposes? Also do you think it's a good idea to do not change context on viewModel and then just do this
launch {
 updateView()
 doLogin(username,password)
 updateView()
}
s

streetsofboston

03/03/2020, 12:35 PM
Instead of hard-coding the Dispatchers.IO, inject the io-dispatcher. In your actual code, you'd inject the Dispatcher.IO, in your unit-tests you'd inject the Dispatchers.Unconfined or the TestCoroutineDispatcher.
👍 1
j

Joan Colmenero

03/03/2020, 2:00 PM
I see your point, yes, that was my first idea, to create like a dispatcher provider, so I can mock it on my tests.
Is there a problem if I run the test with the
<http://Dispatchers.IO|Dispatchers.IO>
instead of the
Disptachers.Uncofined
?
t

tjohnn

03/03/2020, 7:45 PM
Unconfined is for unit testing, you’d still be using IO for network or dB calls
View count: 4