perf: Cache patches list instead of just the patches file

This commit is contained in:
oSumAtrIX 2024-02-08 03:56:16 +01:00
parent bb0b78df8a
commit 7a1957d013
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4

View File

@ -15,7 +15,7 @@ import io.ktor.server.routing.*
import io.ktor.util.pipeline.* import io.ktor.util.pipeline.*
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import java.io.File import java.io.ByteArrayOutputStream
import java.net.URL import java.net.URL
import org.koin.ktor.ext.get as koinGet import org.koin.ktor.ext.get as koinGet
@ -151,40 +151,37 @@ fun Application.configureRouting() {
call.respond(apiPatchesRelease) call.respond(apiPatchesRelease)
} }
val fileCache = Caffeine val patchesListCache = Caffeine
.newBuilder() .newBuilder()
.evictionListener<String, File> { _, value, _ -> value?.delete() }
.maximumSize(1) .maximumSize(1)
.build<String, File>() .build<String, ByteArray>()
get("/list") { get("/list") {
val patchesRelease = val patchesRelease =
backend.getRelease(configuration.organization, configuration.patchesRepository) backend.getRelease(configuration.organization, configuration.patchesRepository)
// Get the cached patches file or download and cache a new one. val patchesListByteArray = patchesListCache.getIfPresent(patchesRelease.tag) ?: run {
// The old file is deleted on eviction.
val patchesFile = fileCache.getIfPresent(patchesRelease.tag) ?: run {
val downloadUrl = patchesRelease.assets val downloadUrl = patchesRelease.assets
.map { APIAsset(it.downloadUrl) } .map { APIAsset(it.downloadUrl) }
.find { it.type == APIAsset.Type.PATCHES } .find { it.type == APIAsset.Type.PATCHES }
?.downloadUrl ?.downloadUrl
kotlin.io.path.createTempFile().toFile().apply { val patches = kotlin.io.path.createTempFile().toFile().apply {
outputStream().use { URL(downloadUrl).openStream().copyTo(it) } outputStream().use { URL(downloadUrl).openStream().copyTo(it) }
}.let { file ->
PatchBundleLoader.Jar(file).also { file.delete() }
}
ByteArrayOutputStream().use { stream ->
PatchUtils.Json.serialize(patches, outputStream = stream)
stream.toByteArray()
}.also { }.also {
fileCache.put(patchesRelease.tag, it) patchesListCache.put(patchesRelease.tag, it)
it.deleteOnExit()
} }
} }
call.respondOutputStream( call.respondBytes(ContentType.Application.Json) { patchesListByteArray }
contentType = ContentType.Application.Json,
) {
PatchUtils.Json.serialize(
PatchBundleLoader.Jar(patchesFile),
outputStream = this,
)
}
} }
} }
} }