commonMain.tech.skot.model.SKDistantDataWithCache.kt Maven / Gradle / Ivy
package tech.skot.model
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.serialization.KSerializer
import tech.skot.core.SKLog
abstract class SKDistantDataWithCache(
protected val name: String,
private val serializer: KSerializer,
protected open val key: String?,
private val cache: SKPersistor = globalPersistor,
validity: Long? = null,
private val fetchData: suspend () -> D
) : SKDistantData(validity, fetchData) {
override suspend fun newDatedData(): DatedData {
val fetchedData = DatedData(fetchData(), currentTimeMillis())
saveInCache(fetchedData)
return fetchedData
}
protected open val completeKey: String? = key
private fun saveInCache(newData: DatedData) {
CoroutineScope(Dispatchers.Default).launch {
try {
cache.putData(serializer, name, newData.data, completeKey, newData.timestamp)
} catch (ex: Exception) {
SKLog.e(
ex,
"SKDistantDataWithCache Problème à la mise en cache de la donnée $name $key"
)
}
}
}
private val initMutex = Mutex()
private suspend fun initWithCache() {
initMutex.withLock {
if (flow.value == null) {
val cacheDate = cache.getDateOfData(name, completeKey)
if (cacheDate != null) {
try {
flow.value = cache.getData(serializer, name, completeKey)?.let {
DatedData(it, cacheDate)
}
} catch (ex: Exception) {
SKLog.e(
ex,
"SKDistantDataWithCache Problème à la récupération du cache de la donnée $name $key"
)
}
}
}
}
}
override suspend fun fallBackValue(): D? {
if (flow.value == null) {
initWithCache()
}
return super.fallBackValue()
}
override suspend fun get(validity: Long?): D {
if (flow.value == null) {
initWithCache()
}
return super.get(validity)
}
override fun setDatedData(newDatedData: DatedData) {
super.setDatedData(newDatedData)
saveInCache(newDatedData)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy