rkeazor
07/21/2020, 4:43 AMMaciek
07/21/2020, 2:33 PMlaunch
block? No context switching, same thread. Simple MainScope().launch {}
. Is there a way to run it sequentially or at least with smaller delays?Justin Tullgren
07/21/2020, 2:55 PMsuspendCancellableCoroutine
being called in a runBlocking
or runBlockingTest
context and using the same dispatcher (Test Dispatcher) block while waiting for a java callback that it wraps? The API that suspendCancellableCoroutine
wraps spawns a Java thread.Leeway
07/21/2020, 6:02 PMVlad
07/21/2020, 8:03 PMchannel.consumeEach { }
but not close channel on cancel. consumeEach does not close BroadcastChannel nor ConflatedBroadcastChannel on cancelation. Should i just stick to
for(it in channel){
}
and create my own helper extension function?Maciek
07/22/2020, 6:24 AMTolriq
07/22/2020, 7:41 AMDaniel Gruber
07/22/2020, 7:56 AMVipul
07/22/2020, 5:41 PMremoteCloudDataStore.getFoodItems()
and localDataStore.addFoodItems(it)
methods are called exactly once
fun getFoodItems(forceNetworkFetch: Boolean) = remoteCloudDataStore.getFoodItems().flatMapConcat {
localDataStore.addFoodItems(it).flatMapConcat {
flow { emit(FoodResult.Success(it)) }
}
}.flowOn(<http://dispatcher.io|dispatcher.io>)
Below is my test case
repository.getFoodItems(true).collect {
verify(exactly = 1) { remoteCloudDataStore.getFoodItems() }
verify(exactly = 5) { localDataStore.addFoodItems(any()) }
}
Surprisingly this test case pass, even if addFoodItems() method is not being called 5 times, can someone point me in correct direction what I am doing wrong here? I am passing TestCoroutineDispatcher
during testing.sean
07/22/2020, 9:19 PMsuspend
function out of a block and raises this:
But what if the extracted function contains a coroutine builder which is invoked on the current scope? In this case, theIt offers a few options:modifier on the extracted function is not enough.suspend
MakingI agree that it doesn't make the API clearer and usually extensions onan extension method ondoWorld
is one of the solutions, but it may not always be applicable as it does not make the API clearer.CoroutineScope
CoroutineScope
are reserved for things that return immediately like the coroutine builders. Roman offered a great convention around this in a talk or blog post I believe.
The idiomatic solution is to have either an explicitThis makes me 🤔 . Wouldn't a more idiomatic solution be to useas a field in a class containing the target function or an implicit one when the outer class implementsCoroutineScope
.CoroutineScope
coroutineScope
or supervisorScope
from the suspend
function that would 1) respect structured concurrency since the scope that is created would be a child of the scope that the suspend
function was called from and 2) give you a CoroutineScope
that would allow you to call your coroutine builder like launch
, etc.?Houssem Zaier
07/23/2020, 7:37 AMAhmed Ibrahim
07/23/2020, 11:18 AMfetchSaleWithPhotosById
returns a Flow<SaleEntity?>
instead of a List, however it still compiles.
override fun read(key: SalesRequestKey): Flow<List<Sale>> = flow {
when (key) {
SalesRequestKey.AllSales -> emitAll(
salesLocalDataSource.fetchAllSales()
.map { saleEntities -> saleEntities.map(saleEntityToDomainSaleEntityMapper) }
)
is SalesRequestKey.SingleSaleRequest -> emitAll(
salesLocalDataSource.fetchSaleWithPhotosById(
key.saleId
).filterNotNull()
.map { saleEntity -> saleEntityToDomainSaleEntityMapper.invoke(saleEntity) }
)
}
Maciek
07/23/2020, 11:21 AMpedro
07/23/2020, 12:20 PMAndrea Giuliano
07/23/2020, 7:43 PMval myScope = CoroutineScope(Executors.newFixedThreadPool(1).asCoroutineDispatcher())
@Test
fun testCoroutines() = runBlocking<Unit>(myScope.coroutineContext) {
myScope.launch() {
println("first 1")
delay(100)
println("first 2")
}
myScope.launch() { println("second") }
}
Can someone explain to me why I will never see “first 2" printed?
if I dont use myscope.launch all works as expected and I see the 3 lines printed. That makes sense since the launch coroutines inherit the scope from runBlocking. But if I set it explicitly something changes not sure why (edited)Andrea Giuliano
07/24/2020, 7:43 AMclass AsyncEventBus(
private val eventBusScope: CoroutineScope
) : EventBus {
private val eventListeners: MutableMap<Class<*>, MutableList<EventListener<*>>> = mutableMapOf()
override fun <E : Event> registerListener(aClass: Class<out E>, eventListener: EventListener<E>) {
val listeners = retrieveListeners(aClass)
listeners.add(eventListener)
}
override fun <E : Event> notify(event: E) {
eventListeners[event::class.java]?.asSequence()
?.filterIsInstance<EventListener<E>>()
?.forEach {
eventBusScope.launch {
it.handle(event)
}
}
}
@Suppress("UNCHECKED_CAST")
private fun <E : Event> retrieveListeners(aClass: Class<out E>): MutableList<EventListener<E>> =
eventListeners.getOrPut(aClass) { mutableListOf() } as MutableList<EventListener<E>>
}
My questions on my code (apart from whether I’m not following best practices for some reasons) are:
• is there anything that can happen that I’m not considering?
• I’m happy that the EventListener handle is not a suspending function since I wanted to make it transparent to who implements handle(). Of course this has the drawback that if someone start to use async blocks into the handle() function (with a different scope) it may find that code to run even though the listener has been killed. Is this something I should be scared about? or is it fair to say that if the handle() goes async, you will take care of what can happen?Maciek
07/24/2020, 8:07 AMahmad
07/24/2020, 7:34 PMfun main() {
val observable = Observable.create<Int> { emitter ->
for (i in 1..5) {
emitter.onNext(i)
}
emitter.onComplete()
}
observable.asFlow().onEach {
println("Flow: $it")
}
}
Why this code doesn’t print anything?Marcelo Hernandez
07/24/2020, 8:34 PMGabriel Feo
07/24/2020, 9:51 PMdata class State(action: Action, list: ListState)
fun getState(events: Flow<ViewEvent>): Flow<State> {
return combine(
getActionState(events).onStart { emit(Action.None) },
getListState().onStart { emit(ListState.Loading) }
) { action, lovedOnesState ->
State(action, lovedOnesState)
}
}
If a ListState change causes a new State to be emitted, the next ViewEvents need to be reduced against this new State, and vice-versa, that's why I combineJustin
07/25/2020, 12:35 AMlaunch {
launch {}
launch {}
launch {}
}.join()
over this?
listOf(
launch {},
launch {},
launch {}
).joinAll()
Either way, why? Thanks!dimsuz
07/25/2020, 6:44 PMscan
in my Flow chain, it starts to act strange — items emitted by channels stop arriving into it. I tried to come up with minimal example to reproduce, posted on SO, would be grateful if anyone could take a look and help:
https://stackoverflow.com/q/63092171/258848torres
07/26/2020, 8:35 AMurls.map {
GlobalScope.async { fetchLink(it) }
}.awaitAll().flatMap { it }
versus doing this?
urls.map {
GlobalScope.async { fetchLink(it) }
}.flatMap { it.await() }
Ananiya
07/27/2020, 11:48 AMSlackbot
07/27/2020, 1:25 PMAndrea Giuliano
07/27/2020, 7:14 PMrunBlocking {
launch { dosomething }
launch { throw Exception }
}
This is nice because it make your thinking easier, and you are pretty much saying: here’s all I need to do, do that in parallel and in case something happens fail everything.
Now my question is this: what if I want to launch many coroutines that are independent from each other? I take the example of threadpool when on many threads you launch some operation but one thread throwing exception does not affect the others. Imagine that on each coroutine I’m handling a separate http request for example.
From the official doc, apart from handling explicitly the exception handling, I haven’t seen any of such examples and I wonder: is the price of launching coroutines that easy paid off when you really want to go in parallel with no noisy neighbours?zak.taccardi
07/27/2020, 10:18 PMval isLoggedIn: Flow<Boolean>
that can emit true
or false
in any order and multiple times each - what would be the best way to observe when it switches from true
to false
? I would like to run a function when the user logs out - meaning the Flow<Boolean>
emits true
then false
?
val isLoggedIn: Flow<Boolean>
isLoggedIn
// <-- what operators do I need here?
.onEach {
onLogout()
}
.launchIn(scope)
taer
07/28/2020, 10:22 PMoffer
will be blocking. I the right way to offer to this queue is with runInterruptibe
?dayanruben
07/29/2020, 2:36 PMAG
07/29/2020, 7:15 PMBroadcastChannel
and StateFlow
to become stable?