Oleg Shuliak
08/29/2023, 9:31 AMsuspend fun filterNonDisplayableActions(allActions: List<Action>, context: Context): List<Action> {
return allActions
.filter {
supervisorScope {
async {
canDisplay(it, context)
}
}.await()
}
}
suspend fun canDisplay(action: Action, context: Context): Boolean {
val actionVisibility = getActionVisibilityClass(action)
return try {
withTimeout(100) {
actionVisibility.isVisibleInCatalog(context)
}
} catch (e: Exception) {
actionVisibility.defaultVisibility()
}
}
I’m trying to iterate on over the list and call canDisplay
on each element using the async/await mechanism to get all result in the end.
Do I do it in right way or should I play around with .awaitAll()
And what would be the best way to test it?
Thanks in advance!Sam
08/29/2023, 9:37 AMreturn allActions.filter { canDisplay(it, context) }
Adding the supervisorScope
and `async`/`await` doesn’t change how the code behaves, because you always wait for the job to complete before proceeding to the next one.Oleg Shuliak
08/29/2023, 9:47 AMcanDisplay()
in parallel.
and once all of those are executed - filter the allActions
listOleg Shuliak
08/29/2023, 9:50 AMasync
will start a coroutine for each elementSam
08/29/2023, 9:52 AMfilter
a little bit tricky, but you could take a shortcut by using null
for the non-matching values. Something like this:
coroutineScope {
allActions.map { action ->
async {
action.takeIf { canDisplay(action, context) }
}
}.awaitAll().filterNotNull()
}
Sam
08/29/2023, 9:53 AMfilter
by using takeIf
followed by filterNotNull
Sam
08/29/2023, 9:53 AMList<Deferred<Action?>>
, which represents the coroutines running in parallel. Then step 2 is awaitAll().filterNotNull()
which waits for the results and removes the ones that didn’t match.Oleg Shuliak
08/29/2023, 9:59 AMSam
08/29/2023, 10:00 AMaction ->
part should have been after the map {
, not the async {
Sam
08/29/2023, 10:00 AMOleg Shuliak
08/29/2023, 10:02 AMOleg Shuliak
08/29/2023, 11:15 AMSam
08/29/2023, 1:23 PMisVisibleInCatalog
implementation, you could have it increment a counter and then awaitCancellation()
. Then you can inspect the counter to see how many coroutines are currently calling that function. After that, advance the virtual time so the timeouts fire and the test completes normally.