rook
04/29/2019, 7:49 PMwithContext(Dispatchers.Default)
over async
? Is withContext
more optimal, somehow?serebit
04/30/2019, 3:46 PMandreworobator
05/01/2019, 12:45 AMwithContext(...)
depending on what they’re doing. If withContext(<http://Dispatchers.IO|Dispatchers.IO>)
always runs on a background thread, how can we ensure single threading for testing purposes? Even runBlocking()
doesn’t affect this.ansman
05/01/2019, 4:49 PMmyScope.launch {
// If the job is canceled before createResourceSync() returns the resource is lost in transit
val resource = withContext(Dispatchers.default) { createResourceSync() }
try {
} finally {
resource.delete()
}
}
basher
05/02/2019, 12:30 AMJob
, is the job cancelled if that object and the job are collected?Paul Woitaschek
05/02/2019, 8:36 AMconcatWith
for Flow?Schadenfreude
05/02/2019, 2:54 PMAuthorizationManager.getToken(context, SCOPES, tokenListener)
I want to wait for it to get the result in the listener and then continue on with my code but I can’t figure out if it’s at all possible.kevin.cianfarini
05/02/2019, 10:37 PMCoroutineScope
being provided in AndroidX LifeCycle as an extension viewModelScope
versus just having viewmodel implement CorutineScope
?Mark
05/03/2019, 3:45 AMfun myFun(): LiveData<MyClass>
to a suspend function that returns as soon as the LiveData value is set (i.e. the first time since LiveData created)? Note - the actual scenario is Room where I sometimes want LiveData<List> and othertimes just want the List of results, but don’t want to specify the SQL annotation twice. The best I have so far is:
suspend fun mySuspendFun() = suspendCoroutine<List<MyClass>> { cont ->
val live = myFun()
live.observeForever(object: Observer<List<MyClass>> {
override fun onChanged(it: List<MyClass>) {
live.removeObserver(this)
cont.resume(it)
}
})
}
kluck
05/03/2019, 7:09 AMDispatchers.Main
on Android. Here are my dependencies:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1")
And on my activity, a simple launch would do nothing when ran on Dispatchers.Main
, whereas it works on `Dispatchers.IO`:
GlobalScope.launch(Dispatchers.Main) { // Works with <http://Dispatchers.IO|Dispatchers.IO>
Timber.d("Current thread: ${Thread.currentThread().name}")
}
In debug, I can access Dispatchers.Main
which is correctly plugged to the android handler.
Any idea what I'm doing wrong?Paul Woitaschek
05/03/2019, 9:01 AMlaunch(Dispatchers.Main) { ... withTimeoutOrNull(1000) }
When I set that timeout to 0
, the tests passes because the views are ready.
Now I thought, that in my tests I can set the main dispatcher for advancing the time automatically (so that the timout is thrown immediately and don't need to adjust the production code for my tests):
Dispatchers.setMain(TestCoroutineDispatcher())
.
However that doesn't work.
Has someone and idea why and how I can fix it?gmaciel
05/03/2019, 9:25 AMCoroutineScope.rxObservable
in production to gradually migrate Rx code into coroutines? Or since it's experimental should wait a little bit and find a different strategy for migration?nwh
05/04/2019, 12:58 AMFlow
could use a chunked
method, just like List
has:
fun <T> Flow<T>.chunked(size: Int) = flow {
val list = mutableListOf<T>()
collect {
list.add(it)
if (list.size == size) {
emit(list.toList())
list.clear()
}
}
if (list.isNotEmpty())
emit(list)
}
Might be good to include in the standard library. Loving the API 👍🏻Hexa
05/04/2019, 6:49 AMFlow
works? I cant seem to find anything on YouTubeSam
05/04/2019, 2:53 PMDico
05/04/2019, 5:58 PMfun CoroutineScope.xxxAsync()
for functions that launch something and return immediately, and suspend fun xxx()
for functions that suspend/block until all of their execution completes.
Much of the kotlinx.coroutines API uses lambdas that are suspend and have a CoroutineScope
receiver. The CoroutineScope
allows developers to write coroutines with cancellability in mind - by checking isActive
. What's the best way to get access to this in a suspend fun
?Paul Woitaschek
05/06/2019, 2:34 PMlaunch {
state.collect {
Timber.i("isActive=$isActive, job=$Job")
render(it)
}
}
It prints isActive=false
. How is that possible?streetsofboston
05/06/2019, 2:58 PMFlow<T>
(successfully or with an error)?
The FlowCollector<T>
only has an emit
method.spierce7
05/06/2019, 7:13 PMJan Skrasek
05/07/2019, 12:24 PM(0..4)
.map { async { .... } }
.forEach {
try {
it.await()...process
} catch() {}
}
Which coroutine scope builder I should use? Using coroutineScope {}
or supervisorScope {}
would cancel the parent or siblings respectively.william
05/07/2019, 12:50 PMwithContext
, am I able to run these in parallel rather then serially?Samer Hobeika
05/07/2019, 6:49 PMGlobalScope.async {
CallA() {
if (it.success) {
GlobalScope.async { CallB( it.value) }
else { LogError() }
} }
louiscad
05/07/2019, 11:45 PMGlobalScope
should not be made experimental with something like @WhyGlobalThingsAreBad
with some details on that special coroutines case of structured concurrency that should not be broken…Marko Mitic
05/08/2019, 12:28 PMSam
05/08/2019, 1:49 PMreturn suspendCoroutine { cont ->
webView.evaluateJavascript( string ) { result ->
cont.resume( result )
}
}
Samer Hobeika
05/08/2019, 5:12 PMzak.taccardi
05/08/2019, 7:22 PMChannel<T>
and Flow<T>
don’t share the same backing interface? It seems unfortunate that the two won’t be able to share the same operatorsstreetsofboston
05/08/2019, 8:00 PMserebit
05/08/2019, 9:14 PMfinally
block because coroutines don't block the program from exiting.louiscad
05/09/2019, 3:57 PMlouiscad
05/09/2019, 3:57 PMkevin.cianfarini
05/09/2019, 4:46 PMrecieve
the element from that channel. Each time you receive, send
to this
channelDominaezzz
05/09/2019, 5:15 PMselect
.Paul Woitaschek
05/09/2019, 6:24 PMbj0
05/09/2019, 8:45 PMselect
in a produce
, but I haven't looked at any of the new Flow
stufflouiscad
05/09/2019, 10:24 PMgaetan
05/09/2019, 10:44 PMbohsen
05/10/2019, 5:53 AMbj0
05/10/2019, 5:57 AMselect
and produce
louiscad
05/10/2019, 7:23 AMConflatedBroadcastChannel
.
I wish I could have a shorter solution that could scale better, that's why I asked.
Also, I have no clue how I can do this with select
and produce
.Dominaezzz
05/10/2019, 8:20 AMlouiscad
05/10/2019, 10:22 AMDominaezzz
05/10/2019, 10:26 AMDataClass(channel1.receive(), channel2.receive(), channel3.receive(), channel4.receive())
?louiscad
05/10/2019, 10:28 AMDominaezzz
05/10/2019, 10:30 AMbj0
05/11/2019, 7:26 AM= produce {
louiscad
05/13/2019, 7:43 AMfun <E1, E2, R> CoroutineScope.combineLatest(
one: ReceiveChannel<E1>,
two: ReceiveChannel<E2>,
transform: (one: E1, two: E2) -> R
): ReceiveChannel<R> {
val output = Channel<R>(capacity = Channel.CONFLATED)
output.invokeOnClose {
one.cancel()
two.cancel()
}
launch {
var latestOne: E1 = one.receive()
var latestTwo: E2 = two.receive()
output.send(transform(latestOne, latestTwo))
while (true) {
select<Unit> {
one.onReceive { latestOne = it }
two.onReceive { latestTwo = it }
}
output.send(transform(latestOne, latestTwo))
}
}.invokeOnCompletion {
one.cancel()
two.cancel()
}
return output
}
(Edited to return ReceiveChannel<T>
.)
Do you think it's correct, especially regarding closing handling?Paulius Ruminas
05/13/2019, 7:51 AMvar latestOne: E1 = one.receive()
var latestTwo: E2 = two.receive()
select<Unit> {
one.onReceive { latestOne = it }
two.onReceive { latestTwo = it }
}
then these statements will throw CancellationException
. Is this the behaviour you want?louiscad
05/13/2019, 8:11 AMlaunch
. I should cancel the two other channels though.
I edited the snippet to return ReceiveChannel<T>
BTW.Paulius Ruminas
05/13/2019, 8:21 AMYes, that shouldn't be a problem since it'll be eaten byBut it will cancel the whole scope if it is notlaunch
Supervised
.
runBlocking {
val a = produce {
while (true) {
delay(1_000)
send(1)
}
}
val b = produce {
while (true) {
delay(2_000)
send(2)
}
}
coroutineScope {
launch {
while (true) {
println("Test")
delay(1_000)
}
}
launch {
combineLatest(a, b) { a, b -> Pair(a, b) }.consumeEach {
println(it)
}
}
delay(10_000)
a.cancel()
}
}
When a.cancel()
is called it will throw an Exception
and cancel the coroutine that prints "Test".louiscad
05/13/2019, 8:25 AMrunBlocking {
launch {}.cancel()
}
doesn't throw because cancellation is not a crash, so it doesn't propagate to parent scope when the coroutine is concurrent (as with launch
or async
).
So I don't see a problem here.Dico
05/13/2019, 3:57 PMonReceive
behaviour.Dominaezzz
05/13/2019, 6:05 PMlouiscad
05/13/2019, 6:18 PM