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

david.bilik

12/18/2019, 1:58 PM
Hi, I have a method in repository that is just calling some api request through retrofit and I want to solve a situation when this method is called multiple times at the same time and it fires multiple requests. Ideal solution for me would be to somehow reuse the same request while it runs. I’ve come up with this but I dont know if there are any problems or if it does not make sense at all. Thanks
Copy code
original function

override suspend fun user(): User {
	return api.user()
}

suggested solution

var userDeferred: Deferred<User>? = null

override suspend fun user(): User {
    if (userDeferred == null) {
        userDeferred = async {
            apiInteractor.user()
        }
    }
    return userDeferred.await().also {
        userDeferred = null
    }
}
u

uhe

12/18/2019, 2:07 PM
That won't compile because
userDeferred
is a nullable property, so
userDeferred.await()
is not allowed. Furthermore, you can still get multiple concurrent calls, because the check for
null
and the assignment are not atomic (if this function is called from different threads).
1
For simple serialization of api calls you could use a
Mutex
and wrap the whole body in a
mutex.withLock
. However, actually piggy-backing on in-flight calls would require another solution.
d

david.bilik

12/18/2019, 2:32 PM
that was just a little polished pseudode, i’ve put some ‼️ while testing it so it compiles .. and yes, i would need to synchronize it to actually have it safe .. but ok, i’ll take a look at the
Mutex
solution, thanks
4 Views