Shawn Witte
10/05/2020, 7:42 AMnative-mt-#
coroutine releases? Dependabot keeps recommending these after the standard releases.neworldlt
10/05/2020, 9:11 AMval foo = runCatching { bar() }.getOrNull() // or similar try-catch block
Xitij
10/05/2020, 9:14 AMsuspend fun jobLifecycle () = coroutineScope {
val job = launch{
println("Working....")
delay(2000L)
println("Done !")
}
delay(1000L)
job.cancel()
// delay(1L) i have to do it to print correct value of job.isCompleted below
println("isCompleted: ${job.isCompleted}") // it is printing "false" but if i delay for some time after cancelling the job it prints "true".
}
is it my computer or it really takes some time to move job from cancelling to cancelled state where isCompleted becomes true after cancellation of job or is there something i'm missing out please review🔦Daniele Segato
10/05/2020, 11:00 AMMutableSharedFlow
. Apologies, as this is a very simplified example from a larger codebase and hopefully it isn't merely demonstrating a gross misuse of SharedFlow
and onSubscription
.
private val counter = AtomicInteger()
class Example {
private val scope = CoroutineScope(Job())
private val _incoming = MutableSharedFlow<Int>(replay = 0)
private val incoming: SharedFlow<String> = _incoming
.onSubscription { emit(-1) }
.map {
// Emulate expensive operator that we want to "share".
delay(500L)
it.toString()
}
.shareIn(scope, replay = 0)
suspend fun request(): String =
incoming
.onSubscription { _incoming.emit(counter.incrementAndGet()) }
.first()
}
fun main() {
val example = Example()
repeat(10) {
val result = runBlocking { example.request() }
println(result)
}
}
Output:
-1
2
3
4
5
6
7
8
9
10
1
was expected after -1
but is missing.Davide Giuseppe Farella
10/06/2020, 9:37 AMsuspend fun getThree() =
withContext(IO) {
val one = async { getOne() }
val two = async { getTwo() }
one.await() + two.await()
}
would be better to be wrapper in a coroutineScope
or would the withContext
be enough?ahulyk
10/06/2020, 1:02 PMjaqxues
10/06/2020, 7:17 PMKush Patel
10/07/2020, 12:40 AMval workers = ArrayList<Future<*>>(10)
try {
for (i in 1..10) {
val task = getTask() ?: break
workers += taskExecutor.submit {
workerLoop(task) // some computation
}
}
} catch (t: Throwable) {
// log error
}
workers.forEach {
try {
it.get()
} catch (t: Throwable) {
// log error
}
}
Proposed coroutine worker
val workers = ArrayList<Deferred<*>>(10)
try {
for (i in 1..10) {
val task = getTask() ?: break
workers += taskExecutor.async {
workerLoop(task) // some computation
}
}
} catch (t: Throwable) {
// Log error
}
runBlocking {
workers.forEach {
try {
it.await()
} catch (t: Throwable) {
// Log error
}
}
}
Is this the right way to switch from threads to coroutines?Pablo
10/07/2020, 9:33 AMSe7eN
10/07/2020, 9:50 AMliveData
builder before like this:
val users = liveData {
emit(getUsers(count=20))
}
With StateFlow, I'm doing it with `lazy`:
val users by lazy {
MutableStateFlow<List<User>>(listOf()).also { usersFlow ->
viewModelScope.launch {
usersFlow.value = getUsers(count = 20)
}
}
}
Just wanna know if it's fine to do it this way?Erik
10/07/2020, 10:42 AMonCreate
I call DebugProbes.install()
. Running the app leads to an immediate crash about java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/android/gms/common/R$string
. 😞 (Note that I don't even need to call DebugProbes.install()
, so the issue lies elsewhere).
Has anybody got experience with debugging Android coroutine stacktraces in production, or any other tips on how to do this?Pablo
10/07/2020, 2:06 PMobobo
10/07/2020, 7:47 PMCoroutineScope
with a SupervisorJob()
and launch
off it, will CoroutineScopes created from its coroutineContext
inherit the SupervisorJob properties? if that second scope launches its own coroutines, will they inherit?agu
10/07/2020, 8:45 PM<http://Dispatchers.IO|Dispatchers.IO>
instead of creating a custom Executor.asCoroutineDispatcher
, supposing that I'm executing IO operations (http calls)Jan Skrasek
10/08/2020, 8:15 AMinterface Foo {
suspend fun test(i: Int)
}
@Test
fun myTest() = testCoroutineDispatcher.runBlockingTest {
val mutableState: MutableStateFlow<Int> = MutableStateFlow(1)
val foo = mockk<Foo>()
val job = launch {
mutableState
.filter { it != 1 }
.collect {
delay(100)
foo.test(it)
}
}
mutableState.value = 2
// how to wait here to be able to verify?
coVerify {
foo.test(2)
}
}
How to wait for the flow collection? Some part of the flow runs immediately and ultimately the execution is switched back to the test and assertion fails since the collection haven't run yet.Ahmed Ibrahim
10/08/2020, 1:10 PM<http://Dispatchers.IO|Dispatchers.IO>.asExecutor()
, but I'm wondering if that would be an appropriate solution since as far as I learned Dispatchers.Default
shares some threads from IO and that might cause another set of problems.
So the question is, would that be a good solution to the problem from multi-threading perspective?sandjelkovic
10/08/2020, 1:38 PMuli
10/08/2020, 2:54 PMMarc Knaup
10/08/2020, 10:06 PMCLOVIS
10/09/2020, 5:14 PMsuspend
modifier to anything that might be expensive, even if it doesn't suspend, to ensure I don't accidentally call it on the main thread.
Do you think it's a good/bad idea? Are there any performance implications of the added parameter? It's a JVM-only project, and I don't care about Java interoperability here.william
10/10/2020, 4:58 PMMarc Knaup
10/10/2020, 6:58 PMAtomicRef
and Deferred
a good approach to ensure that concurrent calls to update()
never cause more than one updateAsync()
execution in parallel?
For example let’s say updateAsync()
execution takes 10 seconds and there are 4 calls to update()
with 2 seconds in between. updateAsync()
would only be called once and they all share the same result, right?Gilles Barbier
10/11/2020, 8:16 AMMarc Knaup
10/11/2020, 1:20 PMshareIn
Flow operator with WhileSubscribed
behavior? I’d like to roughly have that behavior already and swap with shareIn
later on. I have plenty of duplicate executions upstream where I’d like results to be shared.Saiedmomen
10/11/2020, 8:59 PMAll methods of data flow are **thread-safe** and can be safely invoked from concurrent coroutines without
external synchronization.
I wanted to open an issue but wasn't 100% sure so I thought better check it here first and avoid potentially clogging the repos issuesMarc Knaup
10/11/2020, 9:06 PMList<Flow<T>>
into Flow<List<T>>
where List<T>
contains the latest value of each Flow<T>
at the same index. combine()
is not an option.thana
10/12/2020, 6:15 AMactor
is run within?ribesg
10/12/2020, 12:37 PMisActive
instead of true
as an infinite while
loop condition in a coroutine if the loop calls suspending functions (delay
, among others)? I don’t think it changes anything, but maybe it makes things more clear to the reader? Thoughts?Milan Hruban
10/12/2020, 4:17 PMwithContext
call cancellable by timeout?
fun main() = runBlocking<Unit> {
withTimeout(200) {
withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
Thread.sleep(5000)
}
}
}
Marcelo Hernandez
10/12/2020, 9:00 PMObservableSource.asFlow()
has proven, at least for me, to be quite unsafe and can even crash your app. I have several stack traces in https://github.com/Kotlin/kotlinx.coroutines/issues/2104.Marcelo Hernandez
10/12/2020, 9:00 PMObservableSource.asFlow()
has proven, at least for me, to be quite unsafe and can even crash your app. I have several stack traces in https://github.com/Kotlin/kotlinx.coroutines/issues/2104.combine
or flatMapLatest
, or any operators that cause downstream cancellations where ObservableSource.asFlow()
is used in the downstream may run into race conditions where the Coroutine might get cancelled concurrently while the Rx Observable
is still emitting, causing a JobCancellationException
or a ChildCancelledException
.wbertan
10/13/2020, 8:08 AMdispose
which then something finished and throw exception and I got io.reactivex.exceptions.UndeliverableException
(The code contains a proper error handler - where usually was the reason for this error)
So I found this issue in GitHub: https://github.com/ReactiveX/RxJava/issues/4991 with this comment:
This is by design, your Callable crashes and the downstream has disposed so the operator routes the error to the global error handler as it can’t know if the exception is relevant or not. Don’t crash into RxJava and consider using create() with emitter.tryOnError() instead.
Caused by retrofit2.adapter.rxjava2.HttpException
HTTP 404 Client Error
So not sure if in my case I would be able to handle better as the comment suggests with create()
and `emitter.tryOnError()`…
Anyway, it was the first time we notice this kind of Exception like this, and it was in our Alpha build (internal), so we will keep an eye and if becomes more often we will act on it.Marcelo Hernandez
10/23/2020, 7:17 PMObservableSource.asFlow()
crasher has been fixed and will be included in the Coroutines 1.4 release 🎉
https://github.com/Kotlin/kotlinx.coroutines/pull/2333
Thanks @louiscad, @Tash, and @Vsevolod Tolstopyatov [JB] 👏