https://kotlinlang.org logo
#coroutines
Title
# coroutines
b

Brian Dilley

03/23/2021, 5:49 PM
(reposting this question since i did it late at night and it didn’t get any responses): I’ve built a sharding library and i’m trying to add coroutine functionality to it. In the following snippet i’m hoping that it’s doing what I’m thinking it does (returns the first 
true
 result that it finds):
Copy code
override fun emailExists(email: String): Boolean {
        val results = shards.asyncAll { userDao.emailExists(email) }
        return runBlocking {
            results.map { it.await() }
                .firstOrNull { it }
        } ?: false
    }
the shards.asyncAll method is:
Copy code
fun <T> async(
        shardId: Long,
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> T): Deferred<T> {
        return scope.async(context, start) {
            selectShard(shardId)
            block()
        }
    }

    fun <T> asyncAll(
        shardIds: Collection<Long> = this.shardIds,
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> T): List<Deferred<T>> {
        return shardIds.map { async(it, context, start, block) }
    }
So first question is if that code above (
emailExists
) will work, and the second question is: how can i change it so that the first 
Deferred<Boolean>
 result that returns that is 
true
 returns from the method (rather than it testing them in order as they come back - I’d like it so that the very first one that comes back with a result of 
true
 triggers a return)
m

marstran

03/24/2021, 8:02 AM
You should probably use a flow, which is lazy (cold). Then you will only trigger the calls you need.
Copy code
shards.asFlow()
    .map { userDao.emailExists(it) }
    .firstOrNull { it }
With just a list, you will always trigger all of the
emailExists
calls.
b

Brian Dilley

03/24/2021, 3:12 PM
I need to trigger all of them
I just d on my need to wait or check on the others once the first
true
is returned.
m

marstran

03/24/2021, 4:15 PM
One problem here is that returning early will leave the other coroutines running in the background. You lose control over them by returning early . The emailExists function should take a
CoroutineScope
to control that.
By the way, where is the scope variable in
async
coming from?
b

Brian Dilley

03/24/2021, 4:55 PM
from the object that this method is on
5 Views