Browse Source
Before the fix we could cancel a coroutine and the cancelled deferred was saved in cache. ## Release Notes ### Fixes - Resources - _(prerelease fix)_ Fix a cached empty resource on a Compose for Web if the resource loading was canceled during progresspull/4820/head
Konstantin
6 months ago
committed by
GitHub
4 changed files with 57 additions and 64 deletions
@ -0,0 +1,31 @@
|
||||
package org.jetbrains.compose.resources |
||||
|
||||
import kotlinx.coroutines.CoroutineStart |
||||
import kotlinx.coroutines.Deferred |
||||
import kotlinx.coroutines.async |
||||
import kotlinx.coroutines.coroutineScope |
||||
import kotlinx.coroutines.sync.Mutex |
||||
import kotlinx.coroutines.sync.withLock |
||||
|
||||
internal class AsyncCache<K, V> { |
||||
private val mutex = Mutex() |
||||
private val cache = mutableMapOf<K, Deferred<V>>() |
||||
|
||||
suspend fun getOrLoad(key: K, load: suspend () -> V): V = coroutineScope { |
||||
val deferred = mutex.withLock { |
||||
var cached = cache[key] |
||||
if (cached == null || cached.isCancelled) { |
||||
//LAZY - to free the mutex lock as fast as possible |
||||
cached = async(start = CoroutineStart.LAZY) { load() } |
||||
cache[key] = cached |
||||
} |
||||
cached |
||||
} |
||||
deferred.await() |
||||
} |
||||
|
||||
//@TestOnly |
||||
fun clear() { |
||||
cache.clear() |
||||
} |
||||
} |
Loading…
Reference in new issue