Lilly
05/23/2021, 2:05 PM// use case
launch { repoFunc() } // try catch does not work because exceptions are propagated, but not rethrown
// repo
suspend fun repoFunc(scope: CoroutineScope) {
...
scope.launch {
// operation lives as long as application and is only canceled by timeout
try {
withTimeout { someOperation() }
} catch(e: CancellationTimeoutException) {
throw CustomException("Timeout") // How to catch this in the parent?
}
}
}
My question: Are a global CoroutineExceptionHandler, coroutineScope
and supervisorScope
my only options to catch the CustomException
in the parent coroutine?magnumrocha
05/23/2021, 7:28 PMConflatedBroadcastChannel(Unit)
using the StateFlow
or SharedFlow
?
my first try is with a MutableStateFlow<Boolean>(false)
and every time I have a change in my logic that dispatch a signal, I do: myflow.value = !myflow.value
, but this looks weird 😅ursus
05/24/2021, 3:18 AMprivate suspend fun logRemotelyBestEffort(info: LogMessage) {
try {
withTimeout(1000) {
pushApiClient.log(info)
}
} catch (ex: Exception) {
when (ex) {
is TimeoutCancellationException -> Unit
is CancellationException -> throw ex
else -> ...
}
}
}
I hear I'm not supposed to catch CancellationException or I'll break coroutines. But then TimeoutCancellationException extends CancellationException
Is that fine to catch? Or should withContext be outside the try catch?rook
05/24/2021, 1:54 PMDispatcher
is provided during testing?Tucker Barbour
05/24/2021, 3:27 PMCoroutineScope
? e.g.
class MyClass : CoroutineScope by CoroutineScope(Dispatchers.Default) {
fun doSomething() = produce {
trySendBlocking(...)
}
}
The objective is to have MyClass.doSomething
return a ReceiveChannel using produce
. Extending CoroutineScope seemed to be the most straightfoward way to accomplish this.Rashanjyot Arora
05/25/2021, 3:55 AMChristopher Elías
05/25/2021, 4:05 AMflows
😅? My scenario is the following... I'm implementing MVI with unidirectional data flow on an Android Project. When the user enters some screen an initial intent is emitted for load data. The user goes to another screen and when comebacks, the initial intent is triggered again, how can I avoid this? there is some operator? should I create a custom one (someone has a sample like that)?Eugen Martynov
05/25/2021, 11:56 AMAlmas Shagdarov
05/26/2021, 4:21 AMprivate var searchJob: Job? = null
private fun search(query: String = "") {
searchJob?.cancel()
searchJob = viewLifecycleOwner.lifecycleScope.launchWhenStarted {
viewModel.searchTaskList(query).collectLatest {
adapter?.submitData(it)
}
}
}
LeaksCanary: Fragment received onDestroy callback and FragmentManager is null
peekandpoke
05/27/2021, 6:46 AMkotlinx-coroutines 1.5.0
and this now has marked the GlobalScope as a delicate API.
I totally understand the reason behind this but I am somewhat stuck now. So my question is:
How can I create a CoroutineScope
that I will then be reusing? I am doing this now:
val scope = CoroutineScope(EmptyCoroutineContext)
... and then I reuse this scope. Does this make any sense?
And similar in KotlinJS when using Flows we often times have code like this:
fun callApi() {
GlobalScope.launch {
api.getStuff().collect { // collect() is a suspend function so it needs a coroutine scope
...
}
}
}
What would be a clean way to get a reusable coroutine scope here?
Thanks in advance!Lucien Guimaraes
05/27/2021, 3:21 PMhomeRepository
.requestStuff()
.map { stuff -> HomeState.Success(stuff) }
.catch {
emit(HomeState.Error.Unknown(it)) <- type mismatch as FlowCollector is waiting for the HomeState.Success type
}
By adding .filterIsInstance<HomeState>()
before .catch {...}
it works, but I'm wondering if there is a better way 🤔
Thanks!AJ
05/27/2021, 6:54 PMgetViewModelScope().launch {
while (this.isActive) {
val dateString = calendarInteractor.getDateString()
dateStringFlow.value = dateString
log.debug { "sending date string to channel on thread " + ThreadInfo.currentThread() }
dateStringChannel.send(dateString)
delay(100)
}
}
And after going out of the app and returning I am always having a StandaloneCoroutine{Cancelled} for the sending to Channel part, how come? Why does it get cancelled? The launch block is called once and then stops.
Any clues would be appreciatedTim Malseed
05/30/2021, 12:34 PMsuspend fun foo() {
collection.forEach { element ->
withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
// Some long running task processing 'element'
}
}
}
I'm wondering what would be the simplest way to parallelize the long running tasks (each element would be processed in parallel)
I think this is what async
might be for? It's just not something I've used so far, and I'm not sure what the syntax is..Ulrik Rasmussen
05/31/2021, 4:59 AMc
. The first coroutine calls c.send(i)
followed by `c.receive()`; the second does val i = c.receive()
, then checks if i
is even and only then does c.send(i+1)
. The first coroutine will block forever on`c.receive()` if it sent an odd i
in the beginning. It should be possible to reliably detect this situation under the assumption that no other coroutines know c
, and detecting (asynchronously) that the dispatcher is out of work. Preferably I would like to be able to do this in the first coroutine, i.e. effectively doing c.receiveOrThrowOnDeadlock()
.rudolf.hladik
05/31/2021, 12:04 PMkotlinx-coroutines-test
be used in KMM project in commonTest module? or is it still jvm only?Christopher Elías
05/31/2021, 8:43 PM@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
fun <T : Any, U : Any> Observable<T>.notOfType(clazz: Class<U>): Observable<T> {
checkNotNull(clazz) { "clazz is null" }
return filter { !clazz.isInstance(it) }
}
/**
* take only the first ever InitialIntent and all intents of other types
* to avoid reloading data on config changes
*/
private val intentFilter: ObservableTransformer<TasksIntent, TasksIntent>
get() = ObservableTransformer { intents ->
intents.publish { shared ->
Observable.merge(
shared.ofType(TasksIntent.InitialIntent::class.java).take(1),
shared.notOfType(TasksIntent.InitialIntent::class.java)
)
}
}
Is for avoid fire the InitialIntent twice (MVI pattern) can someone know how can I accomplish this? My current implementation of it kinda sucks https://github.com/ChristopherME/counter-android-mvi/blob/685756dca1a6f0e89627cb0e[…]myapplication/presentation/features/counter/CounterViewModel.ktVitaliy Zarubin
06/01/2021, 8:36 AMSudhir Singh Khanger
06/01/2021, 1:28 PMrunBlocking { //room db call }
in onDestroy()
of an Activity
to execute a task which must happen when the Activity
is killed? I could use a lifecycleScope
which wraps both the db call and super.onDestroy()
but I was wondering if that might cause any adverse effects.mbonnin
06/01/2021, 5:45 PMDispatchers.Unconfined
do if it ever needs to dispatch ?
runBlocking {
withContext(Dispatchers.Unconfined) {
withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
// do something in IO here
}
// I am still in an IO thread
delay(10) // dispatch
// what thread am I here?
}
}
ninad thakare
06/01/2021, 10:33 PMplastiv
06/02/2021, 4:21 PMkotlinx-coroutines-android:1.4.3-native-mt
dependency. Can’t find information what does it mean? I need to force -native-mt
variant across my app? Or because I build android application I can safely resolve to normal 1.4.3
variant?Sudhir Singh Khanger
06/03/2021, 4:25 AMrunBlocking {
val scopeJob = Job()
val scope = CoroutineScope(scopeJob)
val job = scope.launch {
}
}
I am unclear on whether job
and scopeJob
are the same. They seem to print different job ids. job
is the Job returned from scope.launch construct in which I have passed a context which which has scopeJob assigned to it. So they should be the same?Ajaydeepak07
06/03/2021, 5:47 AMsuspend fun doCall(list: ArrayList<String>) {
list.forEach {
Api.retrofitService.getProperties(it)
}
}
In this code getProperties() is another suspend function that needs to be called inside doCall() if my list is having more than 1 item for the first item the network call happens and when the iteration comes for next item the list is nullchristophsturm
06/03/2021, 12:25 PMzain
06/04/2021, 3:13 PMval players: SharedFlow<List<Player>> = MutableSharedFlow(,Player("Messi"), Player("Ronaldo"))
Is it possible to collect the changes of a list of object if one item is changed or updated?Marko Novakovic
06/04/2021, 6:06 PMThis job has not completed yet
java.lang.IllegalStateException: This job has not completed yet
at kotlinx.coroutines.JobSupport.getCompletionExceptionOrNull(JobSupport.kt:1190)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest(TestBuilders.kt:53)
at kotlinx.coroutines.test.TestBuildersKt.runBlockingTest$default(TestBuilders.kt:45)
am trying to run some tests and I get this error? what is the cause of it and how to fix it?chansek
06/05/2021, 5:37 AMchannel.offer
is now deprecated. Can anybody please help me understanding the trySend
? I can see 3 flags like isSuccess
, isFailure
and isClosed
. When should I use what?
suspend fun fetch(): Result<List<User>> {
collectFlow {
if (...)
offer(Result.Success(listOf(...)))
else
offer(Result.Error(Exception())
}
}
How this can be converted into trySend
? Shall I use, trySend(Result.Success...).isSuccess
or trySend(Result.Error...).isSuccess
.
When should I use trySend...isFailure
and trySend...isCancel
?Dominaezzz
06/05/2021, 1:06 PMFlow<T>
class members with Flow
?
class Server {
val notificationsFlow: Flow<Notification>
val notifications: Flow<Notification>
}
Do people prefer notifications
or notificationsFlow
?melatonina
06/05/2021, 4:09 PMflatMapLatest
supposed to work correctly with StateFlow
? In the following code:
val locallyAvailableProjectIdsFlow = storageFlow.flatMapLatest {
it?.projectEntityPackageStorage?.projectIdsFlow
?: emptyFlow<WatchState<List<ProjectId>>>().asStateFlow(WatchState.Idle())
}
storageFlow
and projectIdsFlow
are `StateFlow`s, but locallyAvailableProjectIdsFlow
is not being updated.
asStateFlow
is defined as:
private fun <T> Flow<T>.asStateFlow(initialValue: T) =
stateIn(coroutineScope, SharingStarted.Eagerly, initialValue)
Am I doing anything wrong?André Thiele
06/05/2021, 7:35 PMAndré Thiele
06/05/2021, 7:35 PMprivate fun FusedLocationProviderClient.locationFlow(
request: LocationRequest
) = callbackFlow<Location> {
val callback = object : LocationCallback() {
override fun onLocationResult(result: LocationResult?) {
Log.e("Got result", "$result")
result ?: return
try {
offer(result.lastLocation)
} catch (e: Exception) {
// swallow
}
}
}
requestLocationUpdates(
request,
callback,
Looper.getMainLooper()
).addOnFailureListener { e ->
close(e) // in case of exception, close the Flow
}
// clean up when Flow collection ends
awaitClose {
removeLocationUpdates(callback)
}
}