Daniele Segato
09/15/2022, 9:56 AMflatMapLatest
and transformLatest
are still marked with @ExperimentalCoroutinesApi
?Bradleycorn
09/15/2022, 1:19 PMjoin
in a proper manner and/or if there is a better way to do what I’m doing.
I’m launching a coroutine that does some work (makes a few HTTP requests). Then later, in response to some event, I need to launch another coroutine to do some different work. When the 2nd coroutine is launched, I want to make sure the first coroutine is finished before the 2nd one does its work (it’s also ok if the first one was never launched at all). To accomplish this, I’m keeping a reference to the Job
from the first coroutine, and calling its join()
method from the second coroutine. A code sample is included in the 🧵
Two questions:
1. Is it OK to do it this way, or are there any problems with it?
2. Is there some better/more efficient way to do it?oday
09/16/2022, 5:29 PMprivate fun startCoroutines() {
GlobalScope.launch(Dispatchers.Main) {
withTimeout(1000L) {
println("This is executed before the first delay")
stallForTime()
println("This is executed after the first delay")
}
printAfterSomething("the timeout")
}
println("This is executed immediately")
}
suspend fun stallForTime() {
withContext(Dispatchers.Default) {
delay(2000L)
}
}
after the child job inside withTimeout
does not finish in time (because stallForTime made it take too long (2 seconds))
why does the printAfterSomething
not get calledChuck Stein
09/17/2022, 4:55 AMcoroutineScope
function waits for the block's completion before returning, but I want to just launch
something with the current scope, fire and forgetPHondogo
09/18/2022, 7:26 AModay
09/18/2022, 5:33 PMrunTest{ }
to call it, but this is causing me to be unable to answer with the type that I want now, since it’s now expecting TestResult
, I want to return Result.success(obj)
@ExperimentalCoroutinesApi
@Inject
fun firebaseSignInWithEmail(mock: FirebaseSignInWithEmail) {
every {
runTest {
mock.invoke("anyEmail", "anyPassword")
}
} returns TestResult
}
Christopher Porto
09/19/2022, 5:29 PMsuspend fun func1() = CoroutineScope(Dispatchers.Default).launch {
func2()
println("Not called")
}
suspend fun func2() = coroutineScope {
launch {
someFlow.collect { logic.invoke(it) }
}
}
Ben Kosten
09/19/2022, 7:42 PMjava.nio.AsynchronousSocketServerChannel
and I'm using coroutine channels to push my data to a writerChannel
which is responsible for forwarding the data between a client and server. I'm noticing some start delays between when I push data to my channel and when its consumer actually starts.
my code looks like something of the following
//inside the ReadHandler future, push the data read from the socket each time the future completes, also record the start time
val startTime = System.nanoTime()
writerChannel.trySendBlocking(Pair(data, startTime))
//somewhere else in the codebase, consume the data from the channel
scope.launch(Dispatchers.Unconfined) {
writerChannel.consumeEach { (data, startTime) ->
val startElapsed = (System.nanoTime() - startTime) / 1_000_000
println("Took: ${startElapsed}ms to start!")
//do some other stuff with the data
}
}
In one of my tests, I open up 200 simultaneous connections, and every now and then it looks like a coroutine has a cold start of about (2-4)ms with some outliers of upwards of 8ms. Is there any way how I can reduce the amount of time it takes a coroutine to start like that?Rihards
09/20/2022, 12:16 PMThere is no event loop. Use runBlocking { ... } to start one
so I changed coroutine version to 1.6.3-native-mt
. Now the issue is that many other dependencies does not use multithreaded coroutines and I receive errors - is there any way I can force them in my Android project to use this specific version?João Gabriel Zó
09/20/2022, 12:42 PMreactormonk
09/20/2022, 4:00 PMfun onReaderConnected(): Flow<Reader> { ... }
class Reader {
fun onCard(): Flow<Card>
}
And I'm consuming it via
onReaderConnected() { reader ->
reader.onCard().collect {
... process card ...
}
}
Now I've run into the issue where the reader disconnects, the inner collect
won't stop, so the new reader connection won't get activated. How do I best model that?oday
09/21/2022, 12:08 PMSam
09/22/2022, 9:31 AMcollect
is actually run as part of the call to emit
. Use the catch
operator instead if you don’t want that behaviour (I think…)Lukas Lechner
09/22/2022, 1:01 PM.cancellable()
flow operator?reactormonk
09/23/2022, 12:35 PMFlow
which I'm running collectLatest()
on, but it's only firing the first time I send something into it, not the second time... what can be the reasons here?Mikael Ståldal
09/25/2022, 8:48 AMasync { doStuff() }.await()
to make the coroutine cancellable (see code/async/cancelandsuspension.kts
in https://media.pragprog.com/titles/vskotlin/code/vskotlin-code.zip). Is that really a good advice? It seems like the long running blocking code is not cancelled, it is simply detached from the parent coroutine and will continue to run to completion in backround, and will block the completion of the surrounding runBlocking
.
fun getResponse(ms: Int): String {
val s = URL("<http://httpstat.us/200?sleep=$ms>").readText()
println("${LocalTime.now()} Got: $s")
return s
}
suspend fun fetchResponse() = coroutineScope {
try {
println(async { getResponse(4000) }.await())
} catch (ex: CancellationException) {
println("${LocalTime.now()} fetchResponse: ${ex.message}")
}
}
fun main() {
println("${LocalTime.now()} before runBlocking")
runBlocking {
val job = launch(Dispatchers.Default) {
launch { fetchResponse() }
}
println("${LocalTime.now()} Let it run...")
delay(2000)
println("${LocalTime.now()} OK, that's enough, cancel")
job.cancel()
println("${LocalTime.now()} end of runBlocking")
}
println("${LocalTime.now()} after runBlocking")
}
chanjungskim
09/25/2022, 6:03 PMdimsuz
09/26/2022, 12:08 PMStateFlow
or SharedFlow
if the particular flow behaves state-like or share-like? Or is it better to stick to Flow
to be more generic? I was advised to do the latter, but oftentimes I find it useful to do something like onSubscription
which is unavailable for Flow
and having to do stateIn
/ shareIn
when I know that underlying code already has `StateFlow`/`SharedFlow` somehow feels wasteful.Gomathi Gms
09/27/2022, 3:49 PMdimsuz
09/27/2022, 5:46 PMval shared = MutableSharedFlow<Int>()
merge(
shared.onSubscription { shared.emit(3) },
flowOf(100,200,300),
).collect {
println("$it")
}
never prints 3
, only 100 200 300
?
And is there a way to setup this so that I have some point where it is safe to post to shared
to guarantee delivery to collect
?wakingrufus
09/27/2022, 10:10 PMMatteo Mirk
09/29/2022, 7:37 AMalso { }
), to send an event before calling a service. We came up with this, but I think it’s ugly and was wondering if it could be simplified:
override suspend fun validateCart(request: ValidateCartRequest): ValidateCartResponse {
supervisorScope {
launch(Dispatchers.Unconfined) {
domainEventsPublisher.publishCartValidationSubmitted(request.cartId)
}
}
return super.validateCart(request).also { response ->
supervisorScope {
launch(Dispatchers.Unconfined) {
if (response.isValid) domainEventsPublisher.publishCartValidationSucceeded(response)
}
}
}
}
can i wrap everything in a single supervisorScope? Would it be equivalent to this code?George
09/29/2022, 8:25 AMpackage kotlinx.coroutines.flow
. I guess this is for easier discover-ability?. I am wondering if i can use also this pattern when i seem fit in my application code or it is not recommended at all.? Thanks in advance for any help and answers ! Also how come the intelij warning is not suppressed (@file:Suppress("PackageDirectoryMismatch"))? Does not that lead to confusion if the package is intentional or not ?Zoltan Demant
09/29/2022, 9:37 AMNorbi
09/29/2022, 5:02 PMExtentLocal
(in the foreseeable future)?
Thanks.bbaldino
09/30/2022, 4:50 PMSemaphore
that has no available 'permits' to start? I need to launch a coroutine to keep a scope alive, but have it suspend until something else tells it to "go"natario1
09/30/2022, 4:54 PMjob
that was cancelled, cancellation could have been generated either from within job
(e.g. with job.cancel
, or one of its descendants) or by some parent job up the hierarchy. Is there any way to disambiguate between these two cases? I saw that JobCancellationException
has a nice job
field, but it’s not public.John Herrlin
10/01/2022, 11:46 AMChoi
10/02/2022, 3:17 AM<http://Dispatchers.IO|Dispatchers.IO>
.
What does offloading
mean here?Lukas Lechner
10/03/2022, 8:52 AMcollect{}
operator? The docs say that it should be possible to call cancel()
, but that doesn’t seem to work….Lukas Lechner
10/03/2022, 8:52 AMcollect{}
operator? The docs say that it should be possible to call cancel()
, but that doesn’t seem to work….simon.vergauwen
10/03/2022, 8:56 AMcancel()
coming from in that case? 🤔
throw CancellationException
is the first thing that comes to mind, which then probably ends up in a launch
or launchIn
and then the behavior depend on the surrounding CoroutineScope
impl.
What is your use-case for this?Lukas Lechner
10/03/2022, 9:03 AMrunBlocking{}
, and there we have coroutineScope
as receiver, on which cancel can be called.CancellationException
is thrown 🤔 Aren’t CancellationExceptions
special kind of exceptions that don’t lead to crashes?Robert Williams
10/03/2022, 9:10 AMJhonatan Sabadi
10/04/2022, 11:17 AMsimon.vergauwen
10/04/2022, 11:19 AMcancellable
it will inject ensureActive()
in between calls to emit
.
https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/cancellable.html