voben
12/23/2019, 6:53 AMonActive
and onInactive
?Paul Woitaschek
12/23/2019, 10:49 AMmertsimsek
12/23/2019, 11:46 AMOleg Siboglov
12/24/2019, 4:16 PMwithContext
functions since the majority of the use cases require that the code runs sequentially. However, I have one use case where I need to run two of these functions concurrently and then combine the results. My question is if there is would be something wrong with wrapping the withContext
functions with an async
function.
GlobalScope.launch {
val deferredOne = async { doSomeWork() }
val deferredTwo = async { doSomeWork() }
}
suspend fun doSomeWork() = withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
// Do some work here
}
jimn
12/24/2019, 9:58 PMBig Chungus
12/27/2019, 12:30 PMrunBlocking {...}
, but I cannot find anything simmilar on common module.Thiyagu
12/27/2019, 6:58 PMnwh
12/28/2019, 3:19 AMids.map { id ->
async(<http://Dispatchers.IO|Dispatchers.IO>) {
api.getMember(id) // I want to emit this
}
}
Or is there a better-suited construct for this, like a channel?Marc Knaup
12/28/2019, 2:31 PMMarc Knaup
12/28/2019, 2:48 PMsuspend fun main() {
recurse(1)
}
suspend fun recurse(n: Int) {
if (n % 1000 == 0)
delay(1)
println(n)
recurse(n+1)
print("")
}
Question is now how to implement that manually, with @RestrictsSuspension
and without the 1ms penalty 😄
And how to figure out a good n % something
as it depends on the stack size usage of each function in the call stack.Riku
12/29/2019, 8:19 AMRiku
12/29/2019, 8:23 AMmarcoferrer
12/29/2019, 4:49 PMPaul Woitaschek
12/30/2019, 9:53 AMIllegalStateException
because a CancellationException
is a subclass and it puts your application into an unexpected state if you catch it. Just found out the hard wayRuslan Demyanov
12/30/2019, 11:03 AMval channel = ConflatedBroadcastChannel<String>()
launch {
listOf("1", "2", "3", "4", "5", "6").asFlow()
.onEach { Log.d("ORIGIN FLOW(onEach()):", it) }
.collect {
channel.offer("Channel: $it")
}
channel.asFlow()
.onEach {
Log.d("TEST FLOW(onEach()):", it)
}
.flatMapMerge { merge(flow1(), flow2()) }
.collect {
Log.d("TEST FLOW(collect()):", it)
}
}
Mark
12/31/2019, 2:58 AMCoroutineScope
as an argument. In my case, I want to create a factory method to instantiate `MyClass`:
suspend fun createMyClass(scope: CoroutineScope): MyClass {
return MyClass(scope, createMyArg())
}
suspend fun createMyArg(): MyArg {...}
class MyClass(
private val scope: CoroutineScope,
private val myArg: MyArg
)
and I would use it from my AndroidViewModel
like:
viewModelScope.launch {
createMyClass(this).doSomething()
// do some more stuff
}
What is the proper way to write createMyClass()
? For example, how about this?
suspend fun createMyClass(): MyClass {
return MyClass(CoroutineScope(coroutineContext), createMyArg())
}
Lulu
12/31/2019, 8:34 AMCoroutineContext
and CoroutineScope
. I did my research and I also read this article by Elizarov: https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055
He says they're the same thing but they serve different purposes. He explains both of them in the article but he doesn't conclude. So what's the difference after all? I'm very confused.
Just to clarify, I have been using coroutines since they were experimental so I'm not new to the concept, I just started questioning the difference between those two things that I interact with all the time. I know that a scope basically contains a context, but I still don't understand why scopes exist in the first place. Why not just contexts? Or what's the clear distinction between them? (e.g. "the purpose of CoroutineContext
is ... while the purpose of CoroutineScope
is ...")
I feel I'm very close to the answer but I just can't put the pieces together.liminal
12/31/2019, 3:06 PMlookupImagesWithAsync()
should be faster since two images are downloaded in parallel, correct? imageRepository.downloadImage(imagePath)
is a suspend
function that does its work in withContext(<http://Dispatchers.IO|Dispatchers.IO>)
liminal
12/31/2019, 6:56 PMRuntimeException
in imageRepository.downloadImage("img-url-3")
only when getting image3
. Since i am not calling await()
on it, i was expecting the exception to go unnoticed and not propagate to default CoroutineExceptionHandler
and not crash my app. Yet the app crashes still. can someone explain what is different about exception handling when await()
is called vs when it is not? thanks!dave08
01/01/2020, 3:20 PMflow { val result = client.download(url); emit(result) }
instead of using flowOf
?Big Chungus
01/02/2020, 10:59 AMorg.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.3
available for wasm32 target? The dependency fails to resolve for me.Thiyagu
01/02/2020, 2:01 PMonErrorContinue
in kotlin flow?dave08
01/02/2020, 2:28 PMcallbackFlow
, when should I use cancel(CancellationException("....", e))
and when should I just throw the exception? Is there any difference?Thiyagu
01/02/2020, 2:49 PMrunBlocking
lambda? Is any of my coroutine is leaking? https://gist.github.com/thiyagu06/9813da5a5b12ad91ce0ad8b26043d867#file-hangingcoroutines-kt-L79Brian Carbone
01/02/2020, 3:26 PMmyanmarking
01/02/2020, 4:42 PMstorage.findXXX(userId)
.flatMapLatest {
if(it == null){
flowOf(
storage.findYYY(userId)
)
} else{
flowOf(it)
}
}
myanmarking
01/02/2020, 4:43 PMnwh
01/02/2020, 8:47 PMAaron Stacy
01/03/2020, 3:49 AMsuspend fun main() = withContext(Executors.newSingleThreadExecutor().asCoroutineDispatcher()) {}
Even if I call cancel() from within the withContext block, I see an exception logged, but the program just hangs.Thiyagu
01/03/2020, 12:56 PMproducerContext
and consumerContext
will have same CoroutineScope
?does flowScope.cancel()
make both coroutines context not to accept any more task in it?Thiyagu
01/03/2020, 12:56 PMproducerContext
and consumerContext
will have same CoroutineScope
?does flowScope.cancel()
make both coroutines context not to accept any more task in it?tseisel
01/03/2020, 1:20 PMproducerContext
and consumerContext
are 2 independent contexts : one is backed by one thread, the other has a pool of 2 threads.
When collecting from the flow, the code from channelFlow
will be executed on the producer thread, and each element is notified on one of the consumer threads.
Cancelling the flowScope
results in :
1. Cancelling the consumer coroutine (the one started by launchIn
)
2. Cancel collection of the flow, and therefore the block in awaitClose
it called on the producer thread.Thiyagu
01/03/2020, 1:26 PMflowScope.cancel()
is enough stop the flow and both coroutineContext will be stopped. both my context will be having the same scope?tseisel
01/03/2020, 1:55 PMJob
is an unit of work that has a lifecycle : started, stopped, cancelled.
A CoroutineDispatcher
describes how coroutines are executed and resumed. It abstracts threads away.
A CoroutineContext
is the sum of multiple properties. `Job`s and `CoroutineDispatcher`s may be part of a CoroutineContext
.
A CoroutineScope
is the primitive for structured concurrency. It simply wraps a CoroutineContext
, and cancelling a scope indirectly cancels jobs that are part of its context.
From those definitions, we deduce that :
• being based on `CoroutineDispatcher`s, both producerContext
and consumerContext
will not stop, their thread pool will still be allocated.
• Because the producer coroutine in channelFlow
is launched in the scope of its ProducerScope
, it is automatically cancelled when the flow collection is cancelled (you don't need to manually cancel the job in awaitClose
)collect
(or launchIn
in this case) will cancel any upstream operations, including the producer.channelFlow
block by replacing it with the following :
flow {
while(true) {
emit(Random.nextInt(1000)
delay(100)
}
}.buffer()
Thiyagu
01/03/2020, 2:36 PM