David Glasser
08/28/2019, 6:00 AMimport kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.system.exitProcess
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, t ->
println("handling exception: $t")
exitProcess(1)
}
coroutineScope {
launch(handler) {
println("running")
throw Exception("OMG")
}
}
Unit
}
I would expect this to print "handling exception" and exit the process. Instead it shows that an exception was unhandled in main
(I'll paste in the thread)svenjacobs
08/28/2019, 7:30 AMChannel
with Flow
in my Android application. But now I'm stuck in a conceptual thinking problem: Right now I use Channel
to handle UI events on Android views, for instance clicks inside a RecyclerView.Adapter
. I create an instance of Channel
in the view (or presenter, it doesn't matter) and pass it to the RecyclerView.Adapter
. Then inside the adapter I could just pass click events to the channel. But with Flow
, the flow needs to be created at the place where the data is emitted. However I don't want to have x flows in my Adapter for every view the adapter manages. Is Flow
even suited for UI events or are UI events classically hot streams? Am I just trying to apply Flow
where Channel
is the right choice after all?myanmarking
08/28/2019, 2:13 PMmyanmarking
08/28/2019, 2:25 PMIve Vasiljevic
08/28/2019, 6:01 PMPere Casafont
08/29/2019, 2:04 PMsayX()
GlobalScore.launch(Dispatchers.Default) { sayY() }
triggers X but not Y... it looks like the whole coroutines engine goes down. Is that possible?Laura de la rosa
08/29/2019, 2:37 PMivan.savytskyi
08/29/2019, 6:22 PMsvenjacobs
08/30/2019, 6:15 AMval flow1 = flowOf(1, 2, 3)
val flow2 = flowOf(4, 5, 6)
val flow3 = flow1.concat(flow2) // = 1, 2, 3, 4, 5, 6
The order of flow3
does not matter here, so it also might be 1, 4, 2, 5, 3, 6
or any other order, depending on how the values are produced in flow1
and flow2
.thana
08/30/2019, 6:38 AMnewFixedThreadPool
it is backed by an unbounded job queue. is that true for our dispatchers, too?roy
08/30/2019, 7:49 AMsunbreak
08/30/2019, 11:37 AMFlow
like Observable.timeout
?asad.awadia
08/30/2019, 9:35 PMzak.taccardi
08/31/2019, 12:04 AMprivate val channelA = Channel<Int>()
private val channelB = Channel<Int>()
private val flowA: Flow<Int> = channelA.consumeAsFlow()
private val flowB: Flow<Int> = channelB.consumeAsFlow()
suspend fun whenSourceAEmits(value: Int) {
channelA.send(value)
}
suspend fun whenSourceBEmits(value: Int) {
channelB.send(value)
}
sunbreak
08/31/2019, 5:13 AMwithTimeout
doesn’t work on iOS without runBlocking
. Is there another way round?spierce7
08/31/2019, 5:11 PM<http://Dispatchers.IO|Dispatchers.IO>
says:
This dispatcher shares threads with a [Default][Dispatchers.Default] dispatcher, so using
`withContext(<http://Dispatchers.IO|Dispatchers.IO>) { ... }` does not lead to an actual switching to another thread —
typically execution continues in the same thread.*
This behavior seems wrong to me. Isn’t the goal of <http://Dispatchers.IO|Dispatchers.IO>
to keep Dispatchers.Default
threads free. Sharing threads between the dispatchers seems counterintuitive to this goal.Vans239
08/31/2019, 9:36 PMwithTimeout
.
I have a function which can block the thread for undefined time. The caller should get timeout exception after timeout. The function doesn't support cancellation. There is a similar case, but it doesn't work as described. https://stackoverflow.com/questions/47635367/kotlin-coroutines-with-timeout/47641886#47641886
The snippet behind blocks for 10 seconds.
runBlocking {
val work = async { Thread.sleep(10000) }
withTimeout(100) {
work.await()
}
}
There are 3 solutions, which helps to make it working:
- use GlobalScope.async
- use async(NonCancellable + <http://Dispatchers.IO|Dispatchers.IO>)
. Scope will await for async result if i don't specify NonCancellable
. <http://Dispatchers.IO|Dispatchers.IO>
is needed because runBlocking
is single threaded.
- use custom scope
Am I missing something? Is there simpler approach?tseisel
09/01/2019, 7:14 PMclass MyClass(private val scope: CoroutineScope) {
// launches new coroutines in the passed scope
}
Some of my test scenarios requires that the passed CoroutineScope
be cancelled.
How would you write such test with runBlockingTest
?Uchun Lee
09/01/2019, 11:07 PMlaunchCatching(
block = {
getRandomNumber()
},
result = {
println("result is $it")
}
).invokeOnCompletion {
it is Throwable
}
fun <T> CoroutineScope.launchCatching(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T,
result: (result: Result<T>) -> Unit
) = launch(context, start) {
result(
runCatching {
block()
}
)
}
fun <T> CoroutineScope.launchCatching(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T,
onSuccess: (value: T) -> Unit,
onFailure: (exception: Throwable) -> Unit
) = launch(context, start) {
runCatching {
block()
}.fold(
onSuccess,
onFailure
)
}
necati
09/01/2019, 11:19 PMthana
09/02/2019, 2:22 PMfun
that creates a CoroutineExceptionHandler
. when i do launch(exceptionHandler()){throw RuntimeException()}
it gets called but with runBlocking
the exception is not caught. is that expected behavior?Paulius Ruminas
09/02/2019, 4:05 PM@Test
fun example() = runBlockingTest {
val actual = mutableListOf<Int>()
launch {
(0..5).forEach { i ->
supervisorScope {
if (i == 1) cancel()
actual.add(i)
}
}
}
assertEquals(listOf(0, 2, 3, 4, 5), actual)
}
Kroppeb
09/02/2019, 6:48 PMkotlinx.coroutines.io.ByteReadChannel
. How do I read a utf8String of certain length?synhershko
09/03/2019, 7:50 AMtseisel
09/03/2019, 5:28 PMBroadcastChannel
?
I'd like to re-execute the block passed to broadcast
when receiving from it after being closed :
val channel = broadcast<String>(capacity = Channel.CONFLATED, start = LAZY) {
val callback = object : Subscription {
override fun onValue(value: String) {
// May be called multiple times.
offer(value)
}
override fun onError(error: Exception) {
close(error)
}
}
subscribe(callback)
awaitClose { unsubscribe(callback) }
}
// At some point in time, receive latest value from the channel.
// Because the broadcast is lazy, this registers a callback and wait for a value.
// Lets assume that the callback failed, the exception is rethrown here.
channel.consume { receive() }
// At a later time, I'd like "receive" to re-execute the producer coroutine, re-registering a new callback.
channel.consume { receive() }
David Glasser
09/03/2019, 6:27 PM@Test fun foo = runBlocking {
. (We haven't tried using runBlockingTest
since we haven't needed the extra time-related power it brings — but maybe this is the answer to our issue?)
A problem we've been running into is that it's quite easy to have a test whose final line doesn't return Unit. Then the runBlocking doesn't return Unit and neither does the test function, and JUnit just skips it. There is an IntelliJ inspection for this at least but it seems like a bit of a pain. What do people do for this? @Test fun foo: Unit = runBlocking {
? @Test fun foo() { runBlocking {
? Something else?Pablichjenkov
09/03/2019, 8:57 PMFlow
. Or in other words the create
and just
operator equivalents.
Observable
.create(
{ emitter: Emitter<Boolean> ->
// Do stuff and onNext
},
Emitter.BackpressureMode.BUFFER
)
// Also for this
Observable.just(true)
I am using bellow builder but wanted to see other alternatives
flow { flowCollector -> ...// Do stuff and emit }
kevin.cianfarini
09/03/2019, 9:29 PMJob
from a coroutine context?coder82
09/04/2019, 8:47 AMrkeazor
09/04/2019, 11:41 AMrkeazor
09/04/2019, 11:41 AMmarstran
09/04/2019, 11:48 AMwithContext
is like doing await
immediately on the Deferred
from async
. Use async
if you want to do something else while waiting for the Deferred
to complete.louiscad
09/04/2019, 12:09 PMasync
block will cancel the parent scope.
withContext
will only throw and will let you catch without an extra scope.rkeazor
09/04/2019, 12:09 PMlouiscad
09/04/2019, 1:22 PMwithContext
if I need to change the dispatcher.
The only exception might be using flowOn
to make a flow run on a specific dispatcher.
async
is for parallelization in a coroutine.Dominaezzz
09/04/2019, 3:46 PMlouiscad
09/04/2019, 5:45 PM