CLOVIS
08/15/2021, 9:29 AMval cache = HashMap<Id, Deferred<Value>>()
val lock = Semaphore(1)
val cacheJob = SupervisorJob()
val cacheScope = CoroutineScope(cacheJob)
suspend fun get(id: Id) {
val r = lock.withPermit {
if (cache[id] == null) {
val c = CompletableDeferred()
cacheScope.launch {
c.complete(getElementFromNetwork(id))
}
c
} else cache[id]
}
r.await()
}
I think that's generally safe, but I'm not sure if it will correctly handle all cases (the ID is invalid, ...)Dominaezzz
08/15/2021, 9:36 AMDominaezzz
08/15/2021, 9:39 AMCompletableDeferred
here and you've leaked it by not cancelling it.CLOVIS
08/15/2021, 11:37 AMCLOVIS
08/15/2021, 11:38 AMDominaezzz
08/15/2021, 11:38 AMcache
will always be empty.CLOVIS
08/15/2021, 11:40 AMval cache = HashMap<Id, Deferred<Value>>()
val lock = Semaphore(1)
val cacheJob = SupervisorJob()
val cacheScope = CoroutineScope(cacheJob)
suspend fun get(id: Id) {
val r = lock.withPermit {
if (cache[id] == null) {
val c = CompletableDeferred()
cacheScope.launch {
c.complete(getElementFromNetwork(id))
}
cache[id] = c
}
cache[id]
}
r.await()
}
Dominaezzz
08/15/2021, 11:42 AMcache[id] = cacheScope.async { getElementFromNetwork(id) }
?Dominaezzz
08/15/2021, 11:43 AMCompletableDeferred
)CLOVIS
08/15/2021, 1:48 PMget
the same ID, two requests are fired to the server (and the result of the last to terminate will override the other)CLOVIS
08/15/2021, 1:50 PMval cache = HashMap<Id, Pair<StateFlow<Boolean>, StateFlow<Value>>>
This way, the UI can subscribe to either the boolean (whether the value is currently being downloaded) and/or the actual value
This way, it's also possible to get the current value even when another coroutine is updating itDominaezzz
08/15/2021, 2:09 PMephemient
08/15/2021, 6:06 PMval cache = ConcurrentHashMap<Id, Deferred<Value>>()
suspend fun get(id: Id) = coroutineScope {
cache.compute(id) { _, deferred ->
if (deferred == null || try {
deferred.getCompletionExceptionOrNull()
} catch (_: IllegalStateException) {
null
} != null) {
async(start = CoroutineStart.ATOMIC) {
getElementFromNetwork(id)
}
} else deferred
}.await()
}
ephemient
08/15/2021, 6:07 PMDominaezzz
08/15/2021, 6:15 PMephemient
08/15/2021, 6:22 PMephemient
08/15/2021, 6:24 PMRichard Gomez
08/15/2021, 9:43 PMCLOVIS
08/15/2021, 11:00 PMCLOVIS
08/15/2021, 11:01 PMDominaezzz
08/16/2021, 10:36 AMCLOVIS
08/16/2021, 8:23 PM